@danceroutine/tango-core 1.1.3 → 1.3.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/dist/index.js +1 -1
- package/dist/sql/SqlDialect.d.ts +2 -2
- package/dist/sql/SqlIdentifierRole.d.ts +2 -2
- package/dist/sql/index.js +1 -1
- package/dist/{sql-D3frkfy-.js → sql-BI3ptL9-.js} +12 -12
- package/dist/sql-BI3ptL9-.js.map +1 -0
- package/package.json +1 -1
- package/dist/sql-D3frkfy-.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3,6 +3,6 @@ import { isArrayBuffer, isBlob, isDate, isError, isFile, isFormData, isObject, i
|
|
|
3
3
|
import { AuthenticationError, ConflictError, HttpErrorFactory, NotFoundError, PermissionDenied, ValidationError, errors_exports } from "./errors-_tWsmNyZ.js";
|
|
4
4
|
import { TangoBody, TangoHeaders, TangoQueryParams, TangoRequest, TangoResponse, http_exports } from "./http-C17yJ4Pr.js";
|
|
5
5
|
import { ConsoleLogger, getLogger, logging_exports, resetLoggerFactory, setLoggerFactory } from "./logging-BWeD4HOO.js";
|
|
6
|
-
import { SqlSafetyEngine, isTrustedSqlFragment, quoteSqlIdentifier, sql_exports, trustedSql, validateSqlIdentifier } from "./sql-
|
|
6
|
+
import { SqlSafetyEngine, isTrustedSqlFragment, quoteSqlIdentifier, sql_exports, trustedSql, validateSqlIdentifier } from "./sql-BI3ptL9-.js";
|
|
7
7
|
|
|
8
8
|
export { AuthenticationError, ConflictError, ConsoleLogger, HttpErrorFactory, NotFoundError, PermissionDenied, SqlSafetyEngine, TangoBody, TangoError, TangoHeaders, TangoQueryParams, TangoRequest, TangoResponse, ValidationError, errors_exports as errors, getLogger, http_exports as http, isArrayBuffer, isBlob, isDate, isError, isFile, isFormData, isObject, isReadableStream, isTrustedSqlFragment, isURLSearchParams, isUint8Array, logging_exports as logging, quoteSqlIdentifier, resetLoggerFactory, runtime_exports as runtime, setLoggerFactory, sql_exports as sql, trustedSql, validateSqlIdentifier };
|
package/dist/sql/SqlDialect.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const InternalSqlDialect: {
|
|
2
2
|
readonly POSTGRES: "postgres";
|
|
3
3
|
readonly SQLITE: "sqlite";
|
|
4
4
|
};
|
|
5
|
-
export type SqlDialect = (typeof
|
|
5
|
+
export type SqlDialect = (typeof InternalSqlDialect)[keyof typeof InternalSqlDialect];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const InternalSqlIdentifierRole: {
|
|
2
2
|
readonly TABLE: "table";
|
|
3
3
|
readonly COLUMN: "column";
|
|
4
4
|
readonly PRIMARY_KEY: "primaryKey";
|
|
@@ -10,4 +10,4 @@ export declare const INTERNAL_SQL_IDENTIFIER_ROLE: {
|
|
|
10
10
|
readonly RELATION_FOREIGN_KEY: "relationForeignKey";
|
|
11
11
|
readonly RELATION_TARGET_PRIMARY_KEY: "relationTargetPrimaryKey";
|
|
12
12
|
};
|
|
13
|
-
export type SqlIdentifierRole = (typeof
|
|
13
|
+
export type SqlIdentifierRole = (typeof InternalSqlIdentifierRole)[keyof typeof InternalSqlIdentifierRole];
|
package/dist/sql/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { SqlSafetyEngine, isTrustedSqlFragment, quoteSqlIdentifier, trustedSql, validateSqlIdentifier } from "../sql-
|
|
1
|
+
import { SqlSafetyEngine, isTrustedSqlFragment, quoteSqlIdentifier, trustedSql, validateSqlIdentifier } from "../sql-BI3ptL9-.js";
|
|
2
2
|
|
|
3
3
|
export { SqlSafetyEngine, isTrustedSqlFragment, quoteSqlIdentifier, trustedSql, validateSqlIdentifier };
|
|
@@ -15,7 +15,7 @@ const VALIDATED_SQL_IDENTIFIER_BRAND = "tango.core.validated_sql_identifier";
|
|
|
15
15
|
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/sql/SqlIdentifierRole.ts
|
|
18
|
-
const
|
|
18
|
+
const InternalSqlIdentifierRole = {
|
|
19
19
|
TABLE: "table",
|
|
20
20
|
COLUMN: "column",
|
|
21
21
|
PRIMARY_KEY: "primaryKey",
|
|
@@ -32,16 +32,16 @@ const INTERNAL_SQL_IDENTIFIER_ROLE = {
|
|
|
32
32
|
//#region src/sql/validateSqlIdentifier.ts
|
|
33
33
|
const SQL_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
34
34
|
const ROLE_LABELS = {
|
|
35
|
-
[
|
|
36
|
-
[
|
|
37
|
-
[
|
|
38
|
-
[
|
|
39
|
-
[
|
|
40
|
-
[
|
|
41
|
-
[
|
|
42
|
-
[
|
|
43
|
-
[
|
|
44
|
-
[
|
|
35
|
+
[InternalSqlIdentifierRole.TABLE]: "table name",
|
|
36
|
+
[InternalSqlIdentifierRole.COLUMN]: "column",
|
|
37
|
+
[InternalSqlIdentifierRole.PRIMARY_KEY]: "primary key",
|
|
38
|
+
[InternalSqlIdentifierRole.INDEX]: "index",
|
|
39
|
+
[InternalSqlIdentifierRole.ALIAS]: "alias",
|
|
40
|
+
[InternalSqlIdentifierRole.CONSTRAINT]: "constraint",
|
|
41
|
+
[InternalSqlIdentifierRole.SCHEMA]: "schema",
|
|
42
|
+
[InternalSqlIdentifierRole.RELATION_TABLE]: "relation table",
|
|
43
|
+
[InternalSqlIdentifierRole.RELATION_FOREIGN_KEY]: "relation foreign key",
|
|
44
|
+
[InternalSqlIdentifierRole.RELATION_TARGET_PRIMARY_KEY]: "relation target primary key"
|
|
45
45
|
};
|
|
46
46
|
function validateSqlIdentifier(value, role, allowlist) {
|
|
47
47
|
const label = ROLE_LABELS[role];
|
|
@@ -113,4 +113,4 @@ __export(sql_exports, {
|
|
|
113
113
|
|
|
114
114
|
//#endregion
|
|
115
115
|
export { SqlSafetyEngine, isTrustedSqlFragment, quoteSqlIdentifier, sql_exports, trustedSql, validateSqlIdentifier };
|
|
116
|
-
//# sourceMappingURL=sql-
|
|
116
|
+
//# sourceMappingURL=sql-BI3ptL9-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-BI3ptL9-.js","names":["value: unknown","ROLE_LABELS: Record<SqlIdentifierRole, string>","value: string","role: SqlIdentifierRole","allowlist?: readonly string[]","value: unknown","request: SqlSafetyRequest","entry: SqlLookupTokenRequest","entry: SqlRawFragmentRequest","sql: string","identifier: ValidatedSqlIdentifier","_dialect: SqlDialect"],"sources":["../src/sql/TrustedSqlFragment.ts","../src/sql/isTrustedSqlFragment.ts","../src/sql/ValidatedSqlIdentifier.ts","../src/sql/SqlIdentifierRole.ts","../src/sql/validateSqlIdentifier.ts","../src/sql/SqlSafetyEngine.ts","../src/sql/trustedSql.ts","../src/sql/quoteSqlIdentifier.ts","../src/sql/index.ts"],"sourcesContent":["export const TRUSTED_SQL_FRAGMENT_BRAND = 'tango.core.trusted_sql_fragment' as const;\n\nexport type TrustedSqlFragment = {\n readonly __tangoBrand: typeof TRUSTED_SQL_FRAGMENT_BRAND;\n readonly sql: string;\n};\n","import { TRUSTED_SQL_FRAGMENT_BRAND, type TrustedSqlFragment } from './TrustedSqlFragment';\n\n/**\n * Narrow an unknown value to a trusted raw SQL fragment.\n */\nexport function isTrustedSqlFragment(value: unknown): value is TrustedSqlFragment {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TRUSTED_SQL_FRAGMENT_BRAND &&\n typeof (value as { sql?: unknown }).sql === 'string'\n );\n}\n","import type { SqlIdentifierRole } from './SqlIdentifierRole';\n\nexport const VALIDATED_SQL_IDENTIFIER_BRAND = 'tango.core.validated_sql_identifier' as const;\n\nexport type ValidatedSqlIdentifier = {\n readonly __tangoBrand: typeof VALIDATED_SQL_IDENTIFIER_BRAND;\n readonly role: SqlIdentifierRole;\n readonly value: string;\n};\n","export const InternalSqlIdentifierRole = {\n TABLE: 'table',\n COLUMN: 'column',\n PRIMARY_KEY: 'primaryKey',\n INDEX: 'index',\n ALIAS: 'alias',\n CONSTRAINT: 'constraint',\n SCHEMA: 'schema',\n RELATION_TABLE: 'relationTable',\n RELATION_FOREIGN_KEY: 'relationForeignKey',\n RELATION_TARGET_PRIMARY_KEY: 'relationTargetPrimaryKey',\n} as const;\n\nexport type SqlIdentifierRole = (typeof InternalSqlIdentifierRole)[keyof typeof InternalSqlIdentifierRole];\n","import { VALIDATED_SQL_IDENTIFIER_BRAND, type ValidatedSqlIdentifier } from './ValidatedSqlIdentifier';\nimport { InternalSqlIdentifierRole, type SqlIdentifierRole } from './SqlIdentifierRole';\n\nconst SQL_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nconst ROLE_LABELS: Record<SqlIdentifierRole, string> = {\n [InternalSqlIdentifierRole.TABLE]: 'table name',\n [InternalSqlIdentifierRole.COLUMN]: 'column',\n [InternalSqlIdentifierRole.PRIMARY_KEY]: 'primary key',\n [InternalSqlIdentifierRole.INDEX]: 'index',\n [InternalSqlIdentifierRole.ALIAS]: 'alias',\n [InternalSqlIdentifierRole.CONSTRAINT]: 'constraint',\n [InternalSqlIdentifierRole.SCHEMA]: 'schema',\n [InternalSqlIdentifierRole.RELATION_TABLE]: 'relation table',\n [InternalSqlIdentifierRole.RELATION_FOREIGN_KEY]: 'relation foreign key',\n [InternalSqlIdentifierRole.RELATION_TARGET_PRIMARY_KEY]: 'relation target primary key',\n};\n\n/**\n * Validate an identifier against Tango's SQL safety policy.\n */\nexport function validateSqlIdentifier(\n value: string,\n role: SqlIdentifierRole,\n allowlist?: readonly string[]\n): ValidatedSqlIdentifier {\n const label = ROLE_LABELS[role];\n\n if (!SQL_IDENTIFIER_PATTERN.test(value)) {\n throw new Error(`Invalid SQL ${label}: '${value}'.`);\n }\n\n if (allowlist && !allowlist.includes(value)) {\n throw new Error(`Unknown SQL ${label}: '${value}'.`);\n }\n\n return {\n __tangoBrand: VALIDATED_SQL_IDENTIFIER_BRAND,\n role,\n value,\n };\n}\n","import type { SqlDialect } from './SqlDialect';\nimport type { SqlIdentifierRole } from './SqlIdentifierRole';\nimport { isTrustedSqlFragment } from './isTrustedSqlFragment';\nimport type { TrustedSqlFragment } from './TrustedSqlFragment';\nimport { validateSqlIdentifier } from './validateSqlIdentifier';\nimport type { ValidatedSqlIdentifier } from './ValidatedSqlIdentifier';\n\nexport type SqlIdentifierRequest = {\n key: string;\n role: SqlIdentifierRole;\n value: string;\n allowlist?: readonly string[];\n};\n\nexport type SqlLookupTokenRequest = {\n key: string;\n lookup: string;\n allowed: readonly string[];\n};\n\nexport type SqlRawFragmentRequest = {\n key: string;\n value: TrustedSqlFragment;\n};\n\nexport type SqlSafetyRequest = {\n dialect?: SqlDialect;\n identifiers?: readonly SqlIdentifierRequest[];\n lookupTokens?: readonly SqlLookupTokenRequest[];\n rawFragments?: readonly SqlRawFragmentRequest[];\n};\n\nexport type ValidatedSqlLookupToken = {\n lookup: string;\n};\n\nexport type ValidatedSqlSafetyResult = {\n identifiers: Record<string, ValidatedSqlIdentifier>;\n lookupTokens: Record<string, ValidatedSqlLookupToken>;\n rawFragments: Record<string, TrustedSqlFragment>;\n};\n\n/**\n * Canonical SQL safety policy engine shared across Tango packages.\n */\nexport class SqlSafetyEngine {\n static readonly BRAND = 'tango.core.sql_safety_engine' as const;\n readonly __tangoBrand: typeof SqlSafetyEngine.BRAND = SqlSafetyEngine.BRAND;\n\n /**\n * Narrow an unknown value to `SqlSafetyEngine`.\n */\n static isSqlSafetyEngine(value: unknown): value is SqlSafetyEngine {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === SqlSafetyEngine.BRAND\n );\n }\n\n /**\n * Validate a canonical SQL safety request and return trusted tokens.\n */\n validate(request: SqlSafetyRequest): ValidatedSqlSafetyResult {\n return {\n identifiers: Object.fromEntries(\n (request.identifiers ?? []).map((entry) => [\n entry.key,\n validateSqlIdentifier(entry.value, entry.role, entry.allowlist),\n ])\n ),\n lookupTokens: Object.fromEntries(\n (request.lookupTokens ?? []).map((entry) => [entry.key, this.validateLookupToken(entry)])\n ),\n rawFragments: Object.fromEntries(\n (request.rawFragments ?? []).map((entry) => [entry.key, this.validateRawFragment(entry)])\n ),\n };\n }\n\n private validateLookupToken(entry: SqlLookupTokenRequest): ValidatedSqlLookupToken {\n if (!entry.allowed.includes(entry.lookup)) {\n throw new Error(`Unknown lookup: ${entry.lookup}`);\n }\n\n return {\n lookup: entry.lookup,\n };\n }\n\n private validateRawFragment(entry: SqlRawFragmentRequest): TrustedSqlFragment {\n if (!isTrustedSqlFragment(entry.value)) {\n throw new Error(`Untrusted raw SQL fragment for '${entry.key}'.`);\n }\n\n return entry.value;\n }\n}\n","import { TRUSTED_SQL_FRAGMENT_BRAND, type TrustedSqlFragment } from './TrustedSqlFragment';\n\n/**\n * Explicitly opt into embedding a reviewed raw SQL fragment.\n */\nexport function trustedSql(sql: string): TrustedSqlFragment {\n return {\n __tangoBrand: TRUSTED_SQL_FRAGMENT_BRAND,\n sql,\n };\n}\n","import type { SqlDialect } from './SqlDialect';\nimport type { ValidatedSqlIdentifier } from './ValidatedSqlIdentifier';\n\n/**\n * Quote a validated identifier for the target SQL dialect.\n */\nexport function quoteSqlIdentifier(identifier: ValidatedSqlIdentifier, _dialect: SqlDialect): string {\n return `\"${identifier.value.replaceAll('\"', '\"\"')}\"`;\n}\n","/**\n * Domain boundary barrel: centralizes SQL safety primitives and policy helpers.\n */\n\nexport type { SqlDialect } from './SqlDialect';\nexport type { SqlIdentifierRole } from './SqlIdentifierRole';\nexport type { TrustedSqlFragment } from './TrustedSqlFragment';\nexport type { ValidatedSqlIdentifier } from './ValidatedSqlIdentifier';\nexport { SqlSafetyEngine } from './SqlSafetyEngine';\nexport type {\n SqlIdentifierRequest,\n SqlLookupTokenRequest,\n SqlRawFragmentRequest,\n SqlSafetyRequest,\n ValidatedSqlLookupToken,\n ValidatedSqlSafetyResult,\n} from './SqlSafetyEngine';\nexport { trustedSql } from './trustedSql';\nexport { isTrustedSqlFragment } from './isTrustedSqlFragment';\nexport { validateSqlIdentifier } from './validateSqlIdentifier';\nexport { quoteSqlIdentifier } from './quoteSqlIdentifier';\n"],"mappings":";;;MAAa,6BAA6B;;;;ACKnC,SAAS,qBAAqBA,OAA6C;AAC9E,eACW,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,qCAC/C,MAA4B,QAAQ;AAEnD;;;;MCVY,iCAAiC;;;;MCFjC,4BAA4B;CACrC,OAAO;CACP,QAAQ;CACR,aAAa;CACb,OAAO;CACP,OAAO;CACP,YAAY;CACZ,QAAQ;CACR,gBAAgB;CAChB,sBAAsB;CACtB,6BAA6B;AAChC;;;;ACRD,MAAM,yBAAyB;AAE/B,MAAMC,cAAiD;EAClD,0BAA0B,QAAQ;EAClC,0BAA0B,SAAS;EACnC,0BAA0B,cAAc;EACxC,0BAA0B,QAAQ;EAClC,0BAA0B,QAAQ;EAClC,0BAA0B,aAAa;EACvC,0BAA0B,SAAS;EACnC,0BAA0B,iBAAiB;EAC3C,0BAA0B,uBAAuB;EACjD,0BAA0B,8BAA8B;AAC5D;AAKM,SAAS,sBACZC,OACAC,MACAC,WACsB;CACtB,MAAM,QAAQ,YAAY;AAE1B,MAAK,uBAAuB,KAAK,MAAM,CACnC,OAAM,IAAI,OAAO,cAAc,MAAM,KAAK,MAAM;AAGpD,KAAI,cAAc,UAAU,SAAS,MAAM,CACvC,OAAM,IAAI,OAAO,cAAc,MAAM,KAAK,MAAM;AAGpD,QAAO;EACH,cAAc;EACd;EACA;CACH;AACJ;;;;ICIY,kBAAN,MAAM,gBAAgB;CACzB,OAAgB,QAAQ;CACxB,eAAsD,gBAAgB;;;;CAKtE,OAAO,kBAAkBC,OAA0C;AAC/D,gBACW,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,gBAAgB;CAE9E;;;;CAKD,SAASC,SAAqD;AAC1D,SAAO;GACH,aAAa,OAAO,YAChB,CAAC,QAAQ,eAAe,CAAE,GAAE,IAAI,CAAC,UAAU,CACvC,MAAM,KACN,sBAAsB,MAAM,OAAO,MAAM,MAAM,MAAM,UAAU,AAClE,EAAC,CACL;GACD,cAAc,OAAO,YACjB,CAAC,QAAQ,gBAAgB,CAAE,GAAE,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,KAAK,oBAAoB,MAAM,AAAC,EAAC,CAC5F;GACD,cAAc,OAAO,YACjB,CAAC,QAAQ,gBAAgB,CAAE,GAAE,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,KAAK,oBAAoB,MAAM,AAAC,EAAC,CAC5F;EACJ;CACJ;CAED,oBAA4BC,OAAuD;AAC/E,OAAK,MAAM,QAAQ,SAAS,MAAM,OAAO,CACrC,OAAM,IAAI,OAAO,kBAAkB,MAAM,OAAO;AAGpD,SAAO,EACH,QAAQ,MAAM,OACjB;CACJ;CAED,oBAA4BC,OAAkD;AAC1E,OAAK,qBAAqB,MAAM,MAAM,CAClC,OAAM,IAAI,OAAO,kCAAkC,MAAM,IAAI;AAGjE,SAAO,MAAM;CAChB;AACJ;;;;AC5FM,SAAS,WAAWC,KAAiC;AACxD,QAAO;EACH,cAAc;EACd;CACH;AACJ;;;;ACJM,SAAS,mBAAmBC,YAAoCC,UAA8B;AACjG,SAAQ,GAAG,WAAW,MAAM,WAAW,MAAK,OAAK,CAAC;AACrD"}
|
package/package.json
CHANGED
package/dist/sql-D3frkfy-.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sql-D3frkfy-.js","names":["value: unknown","ROLE_LABELS: Record<SqlIdentifierRole, string>","value: string","role: SqlIdentifierRole","allowlist?: readonly string[]","value: unknown","request: SqlSafetyRequest","entry: SqlLookupTokenRequest","entry: SqlRawFragmentRequest","sql: string","identifier: ValidatedSqlIdentifier","_dialect: SqlDialect"],"sources":["../src/sql/TrustedSqlFragment.ts","../src/sql/isTrustedSqlFragment.ts","../src/sql/ValidatedSqlIdentifier.ts","../src/sql/SqlIdentifierRole.ts","../src/sql/validateSqlIdentifier.ts","../src/sql/SqlSafetyEngine.ts","../src/sql/trustedSql.ts","../src/sql/quoteSqlIdentifier.ts","../src/sql/index.ts"],"sourcesContent":["export const TRUSTED_SQL_FRAGMENT_BRAND = 'tango.core.trusted_sql_fragment' as const;\n\nexport type TrustedSqlFragment = {\n readonly __tangoBrand: typeof TRUSTED_SQL_FRAGMENT_BRAND;\n readonly sql: string;\n};\n","import { TRUSTED_SQL_FRAGMENT_BRAND, type TrustedSqlFragment } from './TrustedSqlFragment';\n\n/**\n * Narrow an unknown value to a trusted raw SQL fragment.\n */\nexport function isTrustedSqlFragment(value: unknown): value is TrustedSqlFragment {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === TRUSTED_SQL_FRAGMENT_BRAND &&\n typeof (value as { sql?: unknown }).sql === 'string'\n );\n}\n","import type { SqlIdentifierRole } from './SqlIdentifierRole';\n\nexport const VALIDATED_SQL_IDENTIFIER_BRAND = 'tango.core.validated_sql_identifier' as const;\n\nexport type ValidatedSqlIdentifier = {\n readonly __tangoBrand: typeof VALIDATED_SQL_IDENTIFIER_BRAND;\n readonly role: SqlIdentifierRole;\n readonly value: string;\n};\n","export const INTERNAL_SQL_IDENTIFIER_ROLE = {\n TABLE: 'table',\n COLUMN: 'column',\n PRIMARY_KEY: 'primaryKey',\n INDEX: 'index',\n ALIAS: 'alias',\n CONSTRAINT: 'constraint',\n SCHEMA: 'schema',\n RELATION_TABLE: 'relationTable',\n RELATION_FOREIGN_KEY: 'relationForeignKey',\n RELATION_TARGET_PRIMARY_KEY: 'relationTargetPrimaryKey',\n} as const;\n\nexport type SqlIdentifierRole = (typeof INTERNAL_SQL_IDENTIFIER_ROLE)[keyof typeof INTERNAL_SQL_IDENTIFIER_ROLE];\n","import { VALIDATED_SQL_IDENTIFIER_BRAND, type ValidatedSqlIdentifier } from './ValidatedSqlIdentifier';\nimport { INTERNAL_SQL_IDENTIFIER_ROLE, type SqlIdentifierRole } from './SqlIdentifierRole';\n\nconst SQL_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nconst ROLE_LABELS: Record<SqlIdentifierRole, string> = {\n [INTERNAL_SQL_IDENTIFIER_ROLE.TABLE]: 'table name',\n [INTERNAL_SQL_IDENTIFIER_ROLE.COLUMN]: 'column',\n [INTERNAL_SQL_IDENTIFIER_ROLE.PRIMARY_KEY]: 'primary key',\n [INTERNAL_SQL_IDENTIFIER_ROLE.INDEX]: 'index',\n [INTERNAL_SQL_IDENTIFIER_ROLE.ALIAS]: 'alias',\n [INTERNAL_SQL_IDENTIFIER_ROLE.CONSTRAINT]: 'constraint',\n [INTERNAL_SQL_IDENTIFIER_ROLE.SCHEMA]: 'schema',\n [INTERNAL_SQL_IDENTIFIER_ROLE.RELATION_TABLE]: 'relation table',\n [INTERNAL_SQL_IDENTIFIER_ROLE.RELATION_FOREIGN_KEY]: 'relation foreign key',\n [INTERNAL_SQL_IDENTIFIER_ROLE.RELATION_TARGET_PRIMARY_KEY]: 'relation target primary key',\n};\n\n/**\n * Validate an identifier against Tango's SQL safety policy.\n */\nexport function validateSqlIdentifier(\n value: string,\n role: SqlIdentifierRole,\n allowlist?: readonly string[]\n): ValidatedSqlIdentifier {\n const label = ROLE_LABELS[role];\n\n if (!SQL_IDENTIFIER_PATTERN.test(value)) {\n throw new Error(`Invalid SQL ${label}: '${value}'.`);\n }\n\n if (allowlist && !allowlist.includes(value)) {\n throw new Error(`Unknown SQL ${label}: '${value}'.`);\n }\n\n return {\n __tangoBrand: VALIDATED_SQL_IDENTIFIER_BRAND,\n role,\n value,\n };\n}\n","import type { SqlDialect } from './SqlDialect';\nimport type { SqlIdentifierRole } from './SqlIdentifierRole';\nimport { isTrustedSqlFragment } from './isTrustedSqlFragment';\nimport type { TrustedSqlFragment } from './TrustedSqlFragment';\nimport { validateSqlIdentifier } from './validateSqlIdentifier';\nimport type { ValidatedSqlIdentifier } from './ValidatedSqlIdentifier';\n\nexport type SqlIdentifierRequest = {\n key: string;\n role: SqlIdentifierRole;\n value: string;\n allowlist?: readonly string[];\n};\n\nexport type SqlLookupTokenRequest = {\n key: string;\n lookup: string;\n allowed: readonly string[];\n};\n\nexport type SqlRawFragmentRequest = {\n key: string;\n value: TrustedSqlFragment;\n};\n\nexport type SqlSafetyRequest = {\n dialect?: SqlDialect;\n identifiers?: readonly SqlIdentifierRequest[];\n lookupTokens?: readonly SqlLookupTokenRequest[];\n rawFragments?: readonly SqlRawFragmentRequest[];\n};\n\nexport type ValidatedSqlLookupToken = {\n lookup: string;\n};\n\nexport type ValidatedSqlSafetyResult = {\n identifiers: Record<string, ValidatedSqlIdentifier>;\n lookupTokens: Record<string, ValidatedSqlLookupToken>;\n rawFragments: Record<string, TrustedSqlFragment>;\n};\n\n/**\n * Canonical SQL safety policy engine shared across Tango packages.\n */\nexport class SqlSafetyEngine {\n static readonly BRAND = 'tango.core.sql_safety_engine' as const;\n readonly __tangoBrand: typeof SqlSafetyEngine.BRAND = SqlSafetyEngine.BRAND;\n\n /**\n * Narrow an unknown value to `SqlSafetyEngine`.\n */\n static isSqlSafetyEngine(value: unknown): value is SqlSafetyEngine {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === SqlSafetyEngine.BRAND\n );\n }\n\n /**\n * Validate a canonical SQL safety request and return trusted tokens.\n */\n validate(request: SqlSafetyRequest): ValidatedSqlSafetyResult {\n return {\n identifiers: Object.fromEntries(\n (request.identifiers ?? []).map((entry) => [\n entry.key,\n validateSqlIdentifier(entry.value, entry.role, entry.allowlist),\n ])\n ),\n lookupTokens: Object.fromEntries(\n (request.lookupTokens ?? []).map((entry) => [entry.key, this.validateLookupToken(entry)])\n ),\n rawFragments: Object.fromEntries(\n (request.rawFragments ?? []).map((entry) => [entry.key, this.validateRawFragment(entry)])\n ),\n };\n }\n\n private validateLookupToken(entry: SqlLookupTokenRequest): ValidatedSqlLookupToken {\n if (!entry.allowed.includes(entry.lookup)) {\n throw new Error(`Unknown lookup: ${entry.lookup}`);\n }\n\n return {\n lookup: entry.lookup,\n };\n }\n\n private validateRawFragment(entry: SqlRawFragmentRequest): TrustedSqlFragment {\n if (!isTrustedSqlFragment(entry.value)) {\n throw new Error(`Untrusted raw SQL fragment for '${entry.key}'.`);\n }\n\n return entry.value;\n }\n}\n","import { TRUSTED_SQL_FRAGMENT_BRAND, type TrustedSqlFragment } from './TrustedSqlFragment';\n\n/**\n * Explicitly opt into embedding a reviewed raw SQL fragment.\n */\nexport function trustedSql(sql: string): TrustedSqlFragment {\n return {\n __tangoBrand: TRUSTED_SQL_FRAGMENT_BRAND,\n sql,\n };\n}\n","import type { SqlDialect } from './SqlDialect';\nimport type { ValidatedSqlIdentifier } from './ValidatedSqlIdentifier';\n\n/**\n * Quote a validated identifier for the target SQL dialect.\n */\nexport function quoteSqlIdentifier(identifier: ValidatedSqlIdentifier, _dialect: SqlDialect): string {\n return `\"${identifier.value.replaceAll('\"', '\"\"')}\"`;\n}\n","/**\n * Domain boundary barrel: centralizes SQL safety primitives and policy helpers.\n */\n\nexport type { SqlDialect } from './SqlDialect';\nexport type { SqlIdentifierRole } from './SqlIdentifierRole';\nexport type { TrustedSqlFragment } from './TrustedSqlFragment';\nexport type { ValidatedSqlIdentifier } from './ValidatedSqlIdentifier';\nexport { SqlSafetyEngine } from './SqlSafetyEngine';\nexport type {\n SqlIdentifierRequest,\n SqlLookupTokenRequest,\n SqlRawFragmentRequest,\n SqlSafetyRequest,\n ValidatedSqlLookupToken,\n ValidatedSqlSafetyResult,\n} from './SqlSafetyEngine';\nexport { trustedSql } from './trustedSql';\nexport { isTrustedSqlFragment } from './isTrustedSqlFragment';\nexport { validateSqlIdentifier } from './validateSqlIdentifier';\nexport { quoteSqlIdentifier } from './quoteSqlIdentifier';\n"],"mappings":";;;MAAa,6BAA6B;;;;ACKnC,SAAS,qBAAqBA,OAA6C;AAC9E,eACW,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,qCAC/C,MAA4B,QAAQ;AAEnD;;;;MCVY,iCAAiC;;;;MCFjC,+BAA+B;CACxC,OAAO;CACP,QAAQ;CACR,aAAa;CACb,OAAO;CACP,OAAO;CACP,YAAY;CACZ,QAAQ;CACR,gBAAgB;CAChB,sBAAsB;CACtB,6BAA6B;AAChC;;;;ACRD,MAAM,yBAAyB;AAE/B,MAAMC,cAAiD;EAClD,6BAA6B,QAAQ;EACrC,6BAA6B,SAAS;EACtC,6BAA6B,cAAc;EAC3C,6BAA6B,QAAQ;EACrC,6BAA6B,QAAQ;EACrC,6BAA6B,aAAa;EAC1C,6BAA6B,SAAS;EACtC,6BAA6B,iBAAiB;EAC9C,6BAA6B,uBAAuB;EACpD,6BAA6B,8BAA8B;AAC/D;AAKM,SAAS,sBACZC,OACAC,MACAC,WACsB;CACtB,MAAM,QAAQ,YAAY;AAE1B,MAAK,uBAAuB,KAAK,MAAM,CACnC,OAAM,IAAI,OAAO,cAAc,MAAM,KAAK,MAAM;AAGpD,KAAI,cAAc,UAAU,SAAS,MAAM,CACvC,OAAM,IAAI,OAAO,cAAc,MAAM,KAAK,MAAM;AAGpD,QAAO;EACH,cAAc;EACd;EACA;CACH;AACJ;;;;ICIY,kBAAN,MAAM,gBAAgB;CACzB,OAAgB,QAAQ;CACxB,eAAsD,gBAAgB;;;;CAKtE,OAAO,kBAAkBC,OAA0C;AAC/D,gBACW,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,gBAAgB;CAE9E;;;;CAKD,SAASC,SAAqD;AAC1D,SAAO;GACH,aAAa,OAAO,YAChB,CAAC,QAAQ,eAAe,CAAE,GAAE,IAAI,CAAC,UAAU,CACvC,MAAM,KACN,sBAAsB,MAAM,OAAO,MAAM,MAAM,MAAM,UAAU,AAClE,EAAC,CACL;GACD,cAAc,OAAO,YACjB,CAAC,QAAQ,gBAAgB,CAAE,GAAE,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,KAAK,oBAAoB,MAAM,AAAC,EAAC,CAC5F;GACD,cAAc,OAAO,YACjB,CAAC,QAAQ,gBAAgB,CAAE,GAAE,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,KAAK,oBAAoB,MAAM,AAAC,EAAC,CAC5F;EACJ;CACJ;CAED,oBAA4BC,OAAuD;AAC/E,OAAK,MAAM,QAAQ,SAAS,MAAM,OAAO,CACrC,OAAM,IAAI,OAAO,kBAAkB,MAAM,OAAO;AAGpD,SAAO,EACH,QAAQ,MAAM,OACjB;CACJ;CAED,oBAA4BC,OAAkD;AAC1E,OAAK,qBAAqB,MAAM,MAAM,CAClC,OAAM,IAAI,OAAO,kCAAkC,MAAM,IAAI;AAGjE,SAAO,MAAM;CAChB;AACJ;;;;AC5FM,SAAS,WAAWC,KAAiC;AACxD,QAAO;EACH,cAAc;EACd;CACH;AACJ;;;;ACJM,SAAS,mBAAmBC,YAAoCC,UAA8B;AACjG,SAAQ,GAAG,WAAW,MAAM,WAAW,MAAK,OAAK,CAAC;AACrD"}
|