ts-prorm-orm 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/CHANGELOG.md +1111 -0
  2. package/LICENSE +21 -0
  3. package/README.md +573 -0
  4. package/dist/audit/history-query.js +180 -0
  5. package/dist/audit/index.js +23 -0
  6. package/dist/audit/logger.js +236 -0
  7. package/dist/cache/cache-manager.js +84 -0
  8. package/dist/cache/index.js +16 -0
  9. package/dist/cache/redis-cluster-cache.js +557 -0
  10. package/dist/cli.js +2200 -0
  11. package/dist/compliance/audit-trail.js +68 -0
  12. package/dist/compliance/backup-verification.js +685 -0
  13. package/dist/compliance/breach-detector.js +505 -0
  14. package/dist/compliance/consent-record.js +227 -0
  15. package/dist/compliance/consent-versioning.js +331 -0
  16. package/dist/compliance/cross-border-log.js +530 -0
  17. package/dist/compliance/data-classifier.js +258 -0
  18. package/dist/compliance/data-lineage.js +565 -0
  19. package/dist/compliance/data-masker.js +303 -0
  20. package/dist/compliance/data-portability.js +265 -0
  21. package/dist/compliance/data-retention.js +195 -0
  22. package/dist/compliance/dsar-workflow.js +342 -0
  23. package/dist/compliance/field-encryption.js +223 -0
  24. package/dist/compliance/immutable-record.js +148 -0
  25. package/dist/compliance/index.js +260 -0
  26. package/dist/compliance/privacy-impact-assessment.js +364 -0
  27. package/dist/compliance/pseudonymization.js +269 -0
  28. package/dist/compliance/query-firewall.js +1182 -0
  29. package/dist/compliance/rate-limiter.js +580 -0
  30. package/dist/compliance/right-to-erasure.js +117 -0
  31. package/dist/compliance/row-level-security.js +246 -0
  32. package/dist/compliance/security-decorator.js +574 -0
  33. package/dist/compliance/security-monitor.js +525 -0
  34. package/dist/compliance/sensitive-data-discovery.js +476 -0
  35. package/dist/compliance/session-isolation.js +472 -0
  36. package/dist/compliance/tls-enforcer.js +108 -0
  37. package/dist/compliance/worm-storage.js +712 -0
  38. package/dist/connection-manager.js +198 -0
  39. package/dist/connection-pool.js +519 -0
  40. package/dist/decorators/audit.js +136 -0
  41. package/dist/decorators/belongs-to-many.js +115 -0
  42. package/dist/decorators/belongs-to.js +115 -0
  43. package/dist/decorators/check.js +435 -0
  44. package/dist/decorators/collate.js +329 -0
  45. package/dist/decorators/comment.js +205 -0
  46. package/dist/decorators/database-settings.js +236 -0
  47. package/dist/decorators/default.js +244 -0
  48. package/dist/decorators/encryption.js +235 -0
  49. package/dist/decorators/engine.js +97 -0
  50. package/dist/decorators/fk-constraints.js +594 -0
  51. package/dist/decorators/foreign-table.js +136 -0
  52. package/dist/decorators/generated.js +274 -0
  53. package/dist/decorators/has-many.js +127 -0
  54. package/dist/decorators/has-one.js +116 -0
  55. package/dist/decorators/hstore.js +129 -0
  56. package/dist/decorators/index.js +355 -0
  57. package/dist/decorators/json-column.js +83 -0
  58. package/dist/decorators/jsonb.js +101 -0
  59. package/dist/decorators/orm-decorators.js +425 -0
  60. package/dist/decorators/permissions.js +294 -0
  61. package/dist/decorators/procedure.js +210 -0
  62. package/dist/decorators/query-options.js +556 -0
  63. package/dist/decorators/range.js +167 -0
  64. package/dist/decorators/set-column.js +83 -0
  65. package/dist/decorators/spatial.js +114 -0
  66. package/dist/decorators/storage.js +580 -0
  67. package/dist/decorators/timezone.js +512 -0
  68. package/dist/decorators/trigger.js +90 -0
  69. package/dist/decorators/uuid.js +135 -0
  70. package/dist/decorators/view.js +258 -0
  71. package/dist/diagrams/chen-diagram.js +354 -0
  72. package/dist/diagrams/class-diagram.js +384 -0
  73. package/dist/diagrams/dependency-diagram.js +432 -0
  74. package/dist/diagrams/er-diagram.js +605 -0
  75. package/dist/diagrams/flow-diagram.js +394 -0
  76. package/dist/diagrams/gantt-diagram.js +411 -0
  77. package/dist/diagrams/index-diagram.js +353 -0
  78. package/dist/diagrams/index.js +184 -0
  79. package/dist/diagrams/migration-diagram.js +316 -0
  80. package/dist/diagrams/model-diagram.js +616 -0
  81. package/dist/diagrams/package-diagram.js +376 -0
  82. package/dist/diagrams/palette.js +85 -0
  83. package/dist/diagrams/relational-diagram.js +455 -0
  84. package/dist/diagrams/schemadoc-diagram.js +309 -0
  85. package/dist/diagrams/sequence-diagram.js +307 -0
  86. package/dist/diagrams/state-diagram.js +344 -0
  87. package/dist/diagrams/svg-dom.js +111 -0
  88. package/dist/diagrams/tree-diagram.js +250 -0
  89. package/dist/dialects/clickhouse/index.js +1742 -0
  90. package/dist/dialects/cockroachdb/index.js +4677 -0
  91. package/dist/dialects/cratedb/index.js +441 -0
  92. package/dist/dialects/databricks/index.js +517 -0
  93. package/dist/dialects/db2/index.js +2225 -0
  94. package/dist/dialects/dialect.js +720 -0
  95. package/dist/dialects/duckdb/index.js +2014 -0
  96. package/dist/dialects/exasol/index.js +357 -0
  97. package/dist/dialects/firebird/index.js +495 -0
  98. package/dist/dialects/greenplum/index.js +457 -0
  99. package/dist/dialects/hana/index.js +1741 -0
  100. package/dist/dialects/mariadb/index.js +3590 -0
  101. package/dist/dialects/mssql/index.js +2296 -0
  102. package/dist/dialects/mysql/index.js +4058 -0
  103. package/dist/dialects/oracle/index.js +2999 -0
  104. package/dist/dialects/postgres/index.js +5319 -0
  105. package/dist/dialects/query-stream-helper.js +152 -0
  106. package/dist/dialects/questdb/index.js +433 -0
  107. package/dist/dialects/redshift/index.js +2277 -0
  108. package/dist/dialects/singlestore/index.js +354 -0
  109. package/dist/dialects/snowflake/index.js +2082 -0
  110. package/dist/dialects/spanner/index.js +1768 -0
  111. package/dist/dialects/sqlite/index.js +3382 -0
  112. package/dist/dialects/tidb/index.js +377 -0
  113. package/dist/dialects/timescaledb/index.js +164 -0
  114. package/dist/dialects/trino/index.js +420 -0
  115. package/dist/dialects/turso/index.js +227 -0
  116. package/dist/dialects/vertica/index.js +317 -0
  117. package/dist/dialects/yugabytedb/index.js +424 -0
  118. package/dist/errors/index.js +472 -0
  119. package/dist/errors/utils.js +340 -0
  120. package/dist/errors.js +21 -0
  121. package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
  122. package/dist/extensions/catalog/mssql-features.js +147 -0
  123. package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
  124. package/dist/extensions/catalog/oracle-db2-features.js +196 -0
  125. package/dist/extensions/catalog/postgres-extensions.js +516 -0
  126. package/dist/extensions/index.js +71 -0
  127. package/dist/extensions/types.js +13 -0
  128. package/dist/foreign-data.js +173 -0
  129. package/dist/hooks/hooks-manager.js +350 -0
  130. package/dist/hooks/index.js +37 -0
  131. package/dist/index.js +463 -0
  132. package/dist/logging.js +335 -0
  133. package/dist/migrations/index.js +40 -0
  134. package/dist/migrations/migration.js +196 -0
  135. package/dist/migrations/migrator.js +411 -0
  136. package/dist/migrations/prormmigration.js +275 -0
  137. package/dist/migrations/query-interface.js +435 -0
  138. package/dist/migrations/seeder.js +353 -0
  139. package/dist/models/associations.js +852 -0
  140. package/dist/models/constraints.js +288 -0
  141. package/dist/models/data-types.js +2518 -0
  142. package/dist/models/decorators.js +445 -0
  143. package/dist/models/index.js +33 -0
  144. package/dist/models/indexes.js +531 -0
  145. package/dist/models/methods.js +382 -0
  146. package/dist/models/model-manager.js +103 -0
  147. package/dist/models/model.js +5349 -0
  148. package/dist/models/operators.js +67 -0
  149. package/dist/models/scopes.js +189 -0
  150. package/dist/models/typescript-types.js +26 -0
  151. package/dist/nosql/aerospike/index.js +205 -0
  152. package/dist/nosql/allegrograph/index.js +169 -0
  153. package/dist/nosql/arangodb/index.js +364 -0
  154. package/dist/nosql/azure-blob/index.js +206 -0
  155. package/dist/nosql/beanstalkd/index.js +231 -0
  156. package/dist/nosql/beequeue/index.js +210 -0
  157. package/dist/nosql/bigchaindb/index.js +195 -0
  158. package/dist/nosql/bigtable/index.js +224 -0
  159. package/dist/nosql/blazegraph/index.js +173 -0
  160. package/dist/nosql/bullmq/index.js +191 -0
  161. package/dist/nosql/cassandra/index.js +174 -0
  162. package/dist/nosql/chroma/index.js +190 -0
  163. package/dist/nosql/cloudflare-kv/index.js +220 -0
  164. package/dist/nosql/coherence/index.js +200 -0
  165. package/dist/nosql/cosmosdb/index.js +157 -0
  166. package/dist/nosql/couchbase/index.js +213 -0
  167. package/dist/nosql/dax/index.js +212 -0
  168. package/dist/nosql/deno-kv/index.js +206 -0
  169. package/dist/nosql/dgraph/index.js +171 -0
  170. package/dist/nosql/doris/index.js +169 -0
  171. package/dist/nosql/druid/index.js +162 -0
  172. package/dist/nosql/dynamodb/index.js +937 -0
  173. package/dist/nosql/elasticsearch/index.js +377 -0
  174. package/dist/nosql/etcd/index.js +502 -0
  175. package/dist/nosql/eventhubs/index.js +213 -0
  176. package/dist/nosql/eventstore/index.js +254 -0
  177. package/dist/nosql/faunadb/index.js +188 -0
  178. package/dist/nosql/firestore/index.js +177 -0
  179. package/dist/nosql/fluree/index.js +148 -0
  180. package/dist/nosql/fuseki/index.js +170 -0
  181. package/dist/nosql/gcs/index.js +172 -0
  182. package/dist/nosql/gearman/index.js +160 -0
  183. package/dist/nosql/geode/index.js +196 -0
  184. package/dist/nosql/graphdb/index.js +169 -0
  185. package/dist/nosql/graylog/index.js +188 -0
  186. package/dist/nosql/gridgain/index.js +171 -0
  187. package/dist/nosql/hazelcast/index.js +162 -0
  188. package/dist/nosql/hbase/index.js +230 -0
  189. package/dist/nosql/ignite/index.js +173 -0
  190. package/dist/nosql/immudb/index.js +184 -0
  191. package/dist/nosql/index.js +232 -0
  192. package/dist/nosql/infinispan/index.js +200 -0
  193. package/dist/nosql/influxdb/index.js +0 -0
  194. package/dist/nosql/kafka/index.js +234 -0
  195. package/dist/nosql/keyspaces/index.js +189 -0
  196. package/dist/nosql/kinesis/index.js +253 -0
  197. package/dist/nosql/leveldb/index.js +153 -0
  198. package/dist/nosql/lmdb/index.js +160 -0
  199. package/dist/nosql/loki/index.js +201 -0
  200. package/dist/nosql/marklogic/index.js +204 -0
  201. package/dist/nosql/materialize/index.js +145 -0
  202. package/dist/nosql/meilisearch/index.js +154 -0
  203. package/dist/nosql/memcached/index.js +223 -0
  204. package/dist/nosql/milvus/index.js +410 -0
  205. package/dist/nosql/minio/index.js +265 -0
  206. package/dist/nosql/momento/index.js +179 -0
  207. package/dist/nosql/mongodb/index.js +461 -0
  208. package/dist/nosql/nats/index.js +247 -0
  209. package/dist/nosql/nedb/index.js +164 -0
  210. package/dist/nosql/neo4j/index.js +450 -0
  211. package/dist/nosql/neptune/index.js +470 -0
  212. package/dist/nosql/nsq/index.js +200 -0
  213. package/dist/nosql/opensearch/index.js +186 -0
  214. package/dist/nosql/orientdb/index.js +175 -0
  215. package/dist/nosql/papertrail/index.js +200 -0
  216. package/dist/nosql/pinecone/index.js +0 -0
  217. package/dist/nosql/pinot/index.js +133 -0
  218. package/dist/nosql/pouchdb/index.js +172 -0
  219. package/dist/nosql/prometheus/index.js +174 -0
  220. package/dist/nosql/provendb/index.js +147 -0
  221. package/dist/nosql/pubsub/index.js +187 -0
  222. package/dist/nosql/pulsar/index.js +232 -0
  223. package/dist/nosql/qdrant/index.js +295 -0
  224. package/dist/nosql/qldb/index.js +192 -0
  225. package/dist/nosql/r2/index.js +281 -0
  226. package/dist/nosql/rabbitmq/index.js +237 -0
  227. package/dist/nosql/ravendb/index.js +175 -0
  228. package/dist/nosql/redis/index.js +607 -0
  229. package/dist/nosql/redpanda/index.js +237 -0
  230. package/dist/nosql/resque/index.js +203 -0
  231. package/dist/nosql/rethinkdb/index.js +232 -0
  232. package/dist/nosql/rocksdb/index.js +152 -0
  233. package/dist/nosql/rockset/index.js +126 -0
  234. package/dist/nosql/s3/index.js +298 -0
  235. package/dist/nosql/scylladb/index.js +178 -0
  236. package/dist/nosql/signoz/index.js +227 -0
  237. package/dist/nosql/sns/index.js +201 -0
  238. package/dist/nosql/solr/index.js +231 -0
  239. package/dist/nosql/splunk/index.js +227 -0
  240. package/dist/nosql/sqs/index.js +246 -0
  241. package/dist/nosql/stardog/index.js +169 -0
  242. package/dist/nosql/starrocks/index.js +170 -0
  243. package/dist/nosql/store.js +2 -0
  244. package/dist/nosql/sumologic/index.js +213 -0
  245. package/dist/nosql/surrealdb/index.js +179 -0
  246. package/dist/nosql/terminusdb/index.js +151 -0
  247. package/dist/nosql/tigergraph/index.js +469 -0
  248. package/dist/nosql/typesense/index.js +148 -0
  249. package/dist/nosql/unqlite/index.js +157 -0
  250. package/dist/nosql/upstash/index.js +167 -0
  251. package/dist/nosql/vercel-kv/index.js +166 -0
  252. package/dist/nosql/victoriametrics/index.js +213 -0
  253. package/dist/nosql/virtuoso/index.js +169 -0
  254. package/dist/nosql/weaviate/index.js +276 -0
  255. package/dist/operators/index.js +108 -0
  256. package/dist/operators.js +2690 -0
  257. package/dist/prisma-migrate/index.js +38 -0
  258. package/dist/prisma-migrate/migration-generator.js +125 -0
  259. package/dist/prisma-migrate/model-generator.js +172 -0
  260. package/dist/prisma-migrate/relations.js +100 -0
  261. package/dist/prisma-migrate/schema-parser.js +167 -0
  262. package/dist/prisma-migrate/type-mapper.js +40 -0
  263. package/dist/prorm.js +6832 -0
  264. package/dist/query-builders/cte-builder.js +80 -0
  265. package/dist/query-builders/functions/aggregate.js +390 -0
  266. package/dist/query-builders/functions/conditional.js +503 -0
  267. package/dist/query-builders/functions/datetime.js +695 -0
  268. package/dist/query-builders/functions/fulltext.js +439 -0
  269. package/dist/query-builders/functions/index.js +93 -0
  270. package/dist/query-builders/functions/json.js +427 -0
  271. package/dist/query-builders/functions/math.js +399 -0
  272. package/dist/query-builders/functions/string.js +518 -0
  273. package/dist/query-builders/functions/window.js +328 -0
  274. package/dist/query-builders/include-builder.js +323 -0
  275. package/dist/query-builders/index-expression-builder.js +242 -0
  276. package/dist/query-builders/index.js +161 -0
  277. package/dist/query-builders/insert-builder.js +164 -0
  278. package/dist/query-builders/model-helpers.js +38 -0
  279. package/dist/query-builders/order-limit-builder.js +239 -0
  280. package/dist/query-builders/sql-compiler.js +2040 -0
  281. package/dist/query-builders/subquery-builder.js +152 -0
  282. package/dist/query-builders/update-builder.js +182 -0
  283. package/dist/query-builders/view-builder.js +218 -0
  284. package/dist/query-builders/where-builder.js +1532 -0
  285. package/dist/query-interface.js +622 -0
  286. package/dist/query-optimizers/batch-optimizer.js +426 -0
  287. package/dist/query-optimizers/explain-plans.js +415 -0
  288. package/dist/query-optimizers/index.js +51 -0
  289. package/dist/query-optimizers/prepared-statement-cache.js +423 -0
  290. package/dist/query-optimizers/query-hints.js +438 -0
  291. package/dist/query-optimizers/query-optimizer.js +278 -0
  292. package/dist/query-optimizers/slow-query-logger.js +271 -0
  293. package/dist/replica-manager.js +507 -0
  294. package/dist/schema/index.js +15 -0
  295. package/dist/schema/migration-generator.js +374 -0
  296. package/dist/schema/schema-differ.js +549 -0
  297. package/dist/schema/types.js +6 -0
  298. package/dist/sql-constants.js +300 -0
  299. package/dist/sqlite-advanced.js +1047 -0
  300. package/dist/streams/index.js +12 -0
  301. package/dist/streams/transforms.js +178 -0
  302. package/dist/transaction.js +456 -0
  303. package/dist/types/index.js +180 -0
  304. package/dist/user-management.js +127 -0
  305. package/dist/utils/date.js +300 -0
  306. package/dist/utils/index.js +1079 -0
  307. package/dist/utils/string.js +161 -0
  308. package/dist/validators/index.js +19 -0
  309. package/dist/validators/validator.js +911 -0
  310. package/package.json +190 -0
@@ -0,0 +1,476 @@
1
+ "use strict";
2
+ /**
3
+ * SensitiveDataDiscovery
4
+ *
5
+ * Auto-scans models for sensitive data patterns (SSN, credit cards, health IDs, etc.)
6
+ * with support for custom patterns. Supports GDPR, HIPAA, PCI DSS, APPI compliance.
7
+ *
8
+ * Covers ~18 compliance frameworks including:
9
+ * GDPR (Art 25/30/32/44), HIPAA, PCI DSS 3.x, APPI (Japan),
10
+ * NIST SP 800-122, PIPL (China), LGPD (Brazil), CCPA/CPRA,
11
+ * FIPS 199, ISO 29101, and data discovery requirements.
12
+ *
13
+ * Usage:
14
+ * // Scan a model for sensitive fields:
15
+ * const fields = SensitiveDataDiscovery.scan(User);
16
+ * console.log(fields); // [{ field: 'ssn', type: 'SSN', confidence: 0.95 }, ...]
17
+ *
18
+ * // Scan all models in a prorm instance:
19
+ * const allFields = SensitiveDataDiscovery.scanAll(prorm);
20
+ *
21
+ * // Get previously discovered fields:
22
+ * const discovered = SensitiveDataDiscovery.getDiscoveredFields(User);
23
+ *
24
+ * // Auto-protect: add encryption/masking hooks:
25
+ * SensitiveDataDiscovery.autoProtect(User);
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.SensitiveDataDiscovery = void 0;
29
+ exports.registerPattern = registerPattern;
30
+ exports.unregisterPattern = unregisterPattern;
31
+ exports.getPatterns = getPatterns;
32
+ exports.scanModel = scanModel;
33
+ exports.scanAllModels = scanAllModels;
34
+ exports.getDiscoveredFieldsForModel = getDiscoveredFieldsForModel;
35
+ exports.getScanResult = getScanResult;
36
+ exports.autoProtectModel = autoProtectModel;
37
+ exports.generateComplianceReport = generateComplianceReport;
38
+ const field_encryption_1 = require("./field-encryption");
39
+ const data_masker_1 = require("./data-masker");
40
+ // ==================== Built-in Patterns ====================
41
+ const DEFAULT_PATTERNS = [
42
+ // SSN (US)
43
+ {
44
+ id: 'ssn',
45
+ name: 'Social Security Number',
46
+ type: 'SSN',
47
+ pattern: /^(?:\d{3}[-\s]?\d{2}[-\s]?\d{4}|\d{9})$/,
48
+ columnNames: [/ssn/i, /social.?security/i, /social_security/i],
49
+ frameworks: ['GDPR', 'NIST', 'ISO'],
50
+ recommendation: 'encrypt',
51
+ priority: 100,
52
+ },
53
+ // Credit Card
54
+ {
55
+ id: 'credit_card',
56
+ name: 'Credit Card Number',
57
+ type: 'CREDIT_CARD',
58
+ pattern: /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})$/,
59
+ columnNames: [/credit.?card/i, /card.?number/i, /card_number/i, /pan/i, /payment.?card/i],
60
+ frameworks: ['PCI_DSS', 'GDPR'],
61
+ recommendation: 'encrypt',
62
+ priority: 100,
63
+ },
64
+ // Email
65
+ {
66
+ id: 'email',
67
+ name: 'Email Address',
68
+ type: 'EMAIL',
69
+ pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
70
+ columnNames: [/email/i, /email.?address/i, /mail/i],
71
+ frameworks: ['GDPR', 'PIPL', 'LGPD', 'CCPA'],
72
+ recommendation: 'mask',
73
+ priority: 80,
74
+ },
75
+ // Phone
76
+ {
77
+ id: 'phone',
78
+ name: 'Phone Number',
79
+ type: 'PHONE',
80
+ pattern: /^(?:\+?1[-\s.]?)?\(?[0-9]{3}\)?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4}$/,
81
+ columnNames: [/phone/i, /telephone/i, /mobile/i, /cell/i, /fax/i],
82
+ frameworks: ['GDPR', 'APPI', 'PIPL'],
83
+ recommendation: 'mask',
84
+ priority: 80,
85
+ },
86
+ // Health ID
87
+ {
88
+ id: 'health_id',
89
+ name: 'Health Insurance ID',
90
+ type: 'HEALTH_ID',
91
+ pattern: /^[A-Z0-9]{9,20}$/i,
92
+ columnNames: [/health.?id/i, /insurance.?id/i, /member.?id/i, /policy.?number/i, /medicare/i, /medicaid/i],
93
+ frameworks: ['HIPAA', 'GDPR'],
94
+ recommendation: 'encrypt',
95
+ priority: 90,
96
+ },
97
+ // Driver's License
98
+ {
99
+ id: 'drivers_license',
100
+ name: "Driver's License Number",
101
+ type: 'DRIVERS_LICENSE',
102
+ pattern: /^[A-Z0-9]{5,20}$/i,
103
+ columnNames: [/driver.?license/i, /drivers_license/i, /dl.?number/i, /license.?number/i],
104
+ frameworks: ['GDPR', 'NIST'],
105
+ recommendation: 'encrypt',
106
+ priority: 85,
107
+ },
108
+ // Passport
109
+ {
110
+ id: 'passport',
111
+ name: 'Passport Number',
112
+ type: 'PASSPORT',
113
+ pattern: /^[A-Z0-9]{6,9}$/i,
114
+ columnNames: [/passport/i, /passport.?number/i],
115
+ frameworks: ['GDPR', 'APPI', 'NIST'],
116
+ recommendation: 'encrypt',
117
+ priority: 85,
118
+ },
119
+ // Bank Account
120
+ {
121
+ id: 'bank_account',
122
+ name: 'Bank Account Number',
123
+ type: 'BANK_ACCOUNT',
124
+ pattern: /^[0-9]{8,17}$/,
125
+ columnNames: [/bank.?account/i, /account.?number/i, /account_number/i, /routing.?number/i, /aba/i],
126
+ frameworks: ['GDPR', 'PCI_DSS', 'NIST'],
127
+ recommendation: 'encrypt',
128
+ priority: 90,
129
+ },
130
+ // IBAN
131
+ {
132
+ id: 'iban',
133
+ name: 'International Bank Account Number',
134
+ type: 'IBAN',
135
+ pattern: /^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/,
136
+ columnNames: [/iban/i, /swift/i, /bic/i],
137
+ frameworks: ['GDPR', 'PCI_DSS'],
138
+ recommendation: 'encrypt',
139
+ priority: 90,
140
+ },
141
+ // Date of Birth
142
+ {
143
+ id: 'dob',
144
+ name: 'Date of Birth',
145
+ type: 'DATE_OF_BIRTH',
146
+ pattern: /^(?:0?[1-9]|1[0-2])[\/\-](?:0?[1-9]|[12][0-9]|3[01])[\/\-](?:19|20)?\d{2}$/,
147
+ columnNames: [/dob/i, /birth.?date/i, /date.?of.?birth/i, /birthday/i],
148
+ frameworks: ['GDPR', 'HIPAA', 'APPI'],
149
+ recommendation: 'mask',
150
+ priority: 70,
151
+ },
152
+ // IP Address
153
+ {
154
+ id: 'ip_address',
155
+ name: 'IP Address',
156
+ type: 'IP_ADDRESS',
157
+ pattern: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
158
+ columnNames: [/ip.?address/i, /ip_address/i, /ip.?num/i],
159
+ frameworks: ['GDPR', 'NIST'],
160
+ recommendation: 'redact',
161
+ priority: 60,
162
+ },
163
+ // Biometric
164
+ {
165
+ id: 'biometric',
166
+ name: 'Biometric Data',
167
+ type: 'BIOMETRIC',
168
+ pattern: /^[A-Za-z0-9+/]{20,}={0,2}$/, // Base64 encoded biometric
169
+ columnNames: [/fingerprint/i, /face/i, /iris/i, /biometric/i, /voice.?print/i, /retina/i],
170
+ frameworks: ['GDPR', 'HIPAA', 'APPI', 'NIST'],
171
+ recommendation: 'tokenize',
172
+ priority: 95,
173
+ },
174
+ // Medical Record
175
+ {
176
+ id: 'medical_record',
177
+ name: 'Medical Record Number',
178
+ type: 'MEDICAL_RECORD',
179
+ pattern: /^[A-Z0-9]{6,15}$/i,
180
+ columnNames: [/medical.?record/i, /mrn/i, /patient.?id/i, /chart.?number/i],
181
+ frameworks: ['HIPAA', 'GDPR', 'APPI'],
182
+ recommendation: 'encrypt',
183
+ priority: 95,
184
+ },
185
+ // Prescription
186
+ {
187
+ id: 'prescription',
188
+ name: 'Prescription ID',
189
+ type: 'PRESCRIPTION',
190
+ pattern: /^[A-Z0-9]{8,12}$/i,
191
+ columnNames: [/prescription/i, /rx.?number/i, /rxid/i, /script.?id/i],
192
+ frameworks: ['HIPAA', 'GDPR'],
193
+ recommendation: 'encrypt',
194
+ priority: 90,
195
+ },
196
+ // Insurance ID
197
+ {
198
+ id: 'insurance_id',
199
+ name: 'Insurance Policy ID',
200
+ type: 'INSURANCE_ID',
201
+ pattern: /^[A-Z0-9]{9,15}$/i,
202
+ columnNames: [/insurance.?id/i, /policy.?id/i, /group.?number/i, /plan.?id/i],
203
+ frameworks: ['HIPAA', 'GDPR', 'APPI'],
204
+ recommendation: 'encrypt',
205
+ priority: 85,
206
+ },
207
+ // National ID (general)
208
+ {
209
+ id: 'national_id',
210
+ name: 'National Identification Number',
211
+ type: 'NATIONAL_ID',
212
+ pattern: /^[A-Z0-9]{6,20}$/i,
213
+ columnNames: [/national.?id/i, /national_id/i, /gov.?id/i, /id.?number/i, /nin/i, /ssn/i],
214
+ frameworks: ['GDPR', 'APPI', 'PIPL', 'NIST'],
215
+ recommendation: 'encrypt',
216
+ priority: 85,
217
+ },
218
+ ];
219
+ // ==================== Registry ====================
220
+ const DISCOVERY_KEY = '__orm_sensitive_discovery__';
221
+ const SCAN_RESULTS_KEY = '__orm_scan_results__';
222
+ function getDiscoveredMap(target) {
223
+ if (!target[DISCOVERY_KEY]) {
224
+ target[DISCOVERY_KEY] = new Map();
225
+ }
226
+ return target[DISCOVERY_KEY];
227
+ }
228
+ function getScanResults(prorm) {
229
+ if (!prorm[SCAN_RESULTS_KEY]) {
230
+ prorm[SCAN_RESULTS_KEY] = new Map();
231
+ }
232
+ return prorm[SCAN_RESULTS_KEY];
233
+ }
234
+ // Global pattern registry
235
+ const globalPatterns = [...DEFAULT_PATTERNS];
236
+ /**
237
+ * Register a custom discovery pattern.
238
+ */
239
+ function registerPattern(pattern) {
240
+ const existing = globalPatterns.findIndex((p) => p.id === pattern.id);
241
+ if (existing >= 0) {
242
+ globalPatterns[existing] = pattern;
243
+ }
244
+ else {
245
+ globalPatterns.push(pattern);
246
+ }
247
+ }
248
+ /**
249
+ * Remove a custom discovery pattern.
250
+ */
251
+ function unregisterPattern(patternId) {
252
+ const index = globalPatterns.findIndex((p) => p.id === patternId);
253
+ if (index >= 0 && index < DEFAULT_PATTERNS.length) {
254
+ return false; // Cannot remove built-in patterns
255
+ }
256
+ return globalPatterns.splice(index, 1).length > 0;
257
+ }
258
+ /**
259
+ * Get all registered patterns.
260
+ */
261
+ function getPatterns() {
262
+ return [...globalPatterns];
263
+ }
264
+ // ==================== Core Discovery Logic ====================
265
+ /**
266
+ * Scan a single model for sensitive fields.
267
+ */
268
+ function scanModel(Model, options = {}) {
269
+ const { minConfidence = 0.7, matchByName = true, matchByPattern = true, customPatterns = [], targetFrameworks = [], } = options;
270
+ const attributes = Model.rawAttributes ?? {};
271
+ const discovered = [];
272
+ const modelName = Model.name ?? Model.tableName ?? 'Unknown';
273
+ // Combine default and custom patterns
274
+ const patterns = [...globalPatterns, ...customPatterns].sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50));
275
+ // Filter by target frameworks if specified
276
+ const filteredPatterns = targetFrameworks.length > 0
277
+ ? patterns.filter((p) => p.frameworks.some((f) => targetFrameworks.includes(f)))
278
+ : patterns;
279
+ // Check each attribute
280
+ for (const fieldName of Object.keys(attributes)) {
281
+ const columnDef = attributes[fieldName];
282
+ const columnType = columnDef?.type?.toString().toLowerCase() ?? '';
283
+ const columnName = fieldName.toLowerCase();
284
+ for (const pattern of filteredPatterns) {
285
+ let confidence = 0;
286
+ let method = 'column_name';
287
+ let sampleMatch;
288
+ // Check column name matching
289
+ if (matchByName && pattern.columnNames) {
290
+ for (const namePattern of pattern.columnNames) {
291
+ if (namePattern.test(columnName)) {
292
+ confidence = 0.85;
293
+ method = 'column_name';
294
+ break;
295
+ }
296
+ }
297
+ }
298
+ // If column name matched, add to results
299
+ if (confidence >= minConfidence) {
300
+ discovered.push({
301
+ field: fieldName,
302
+ type: pattern.type,
303
+ confidence,
304
+ method,
305
+ pattern: pattern.pattern,
306
+ frameworks: pattern.frameworks,
307
+ recommendation: pattern.recommendation,
308
+ sampleMatch,
309
+ });
310
+ break;
311
+ }
312
+ }
313
+ }
314
+ // Store results
315
+ const map = getDiscoveredMap(Model);
316
+ map.set('latest', {
317
+ fields: discovered,
318
+ scannedAt: new Date(),
319
+ });
320
+ return discovered;
321
+ }
322
+ /**
323
+ * Scan all models in a Prorm instance.
324
+ */
325
+ function scanAllModels(prorm, options = {}) {
326
+ const results = [];
327
+ const models = prorm?.models ?? {};
328
+ for (const [modelName, Model] of Object.entries(models)) {
329
+ const fields = scanModel(Model, options);
330
+ const frameworks = new Set();
331
+ for (const field of fields) {
332
+ for (const fw of field.frameworks) {
333
+ frameworks.add(fw);
334
+ }
335
+ }
336
+ results.push({
337
+ model: Model,
338
+ modelName,
339
+ fields,
340
+ scannedAt: new Date(),
341
+ applicableFrameworks: Array.from(frameworks),
342
+ });
343
+ }
344
+ // Store all results
345
+ const resultsMap = getScanResults(prorm);
346
+ for (const result of results) {
347
+ resultsMap.set(result.modelName, result);
348
+ }
349
+ return results;
350
+ }
351
+ /**
352
+ * Get previously discovered fields for a model.
353
+ */
354
+ function getDiscoveredFieldsForModel(Model) {
355
+ const map = getDiscoveredMap(Model);
356
+ return map.get('latest')?.fields;
357
+ }
358
+ /**
359
+ * Get scan result for a specific model.
360
+ */
361
+ function getScanResult(prorm, modelName) {
362
+ const resultsMap = getScanResults(prorm);
363
+ return resultsMap.get(modelName);
364
+ }
365
+ /**
366
+ * Auto-protect a model by adding encryption/masking hooks.
367
+ */
368
+ function autoProtectModel(Model, options = {}) {
369
+ const fields = scanModel(Model, options);
370
+ for (const sensitive of fields) {
371
+ switch (sensitive.recommendation) {
372
+ case 'encrypt':
373
+ // Apply field encryption
374
+ try {
375
+ field_encryption_1.FieldEncryption.applyHooks?.(Model);
376
+ }
377
+ catch {
378
+ // FieldEncryption may not have applyHooks, use DataMasker as fallback
379
+ data_masker_1.DataMasker.maskField(Model, sensitive.field, { pattern: 'full' });
380
+ }
381
+ break;
382
+ case 'mask':
383
+ // Apply masking
384
+ if (sensitive.type === 'EMAIL') {
385
+ data_masker_1.DataMasker.maskField(Model, sensitive.field, { pattern: 'email' });
386
+ }
387
+ else if (sensitive.type === 'PHONE') {
388
+ data_masker_1.DataMasker.maskField(Model, sensitive.field, { pattern: 'phone' });
389
+ }
390
+ else if (sensitive.type === 'SSN') {
391
+ data_masker_1.DataMasker.maskField(Model, sensitive.field, { pattern: 'ssn' });
392
+ }
393
+ else if (sensitive.type === 'CREDIT_CARD') {
394
+ data_masker_1.DataMasker.maskField(Model, sensitive.field, { pattern: 'card-last4', showLast: 4 });
395
+ }
396
+ else {
397
+ data_masker_1.DataMasker.maskField(Model, sensitive.field, { pattern: 'full' });
398
+ }
399
+ break;
400
+ case 'redact':
401
+ // Full redaction
402
+ data_masker_1.DataMasker.maskField(Model, sensitive.field, { pattern: 'full' });
403
+ break;
404
+ case 'tokenize':
405
+ // Tokenize (using pseudonymization as fallback)
406
+ data_masker_1.DataMasker.maskField(Model, sensitive.field, { pattern: 'full' });
407
+ break;
408
+ }
409
+ }
410
+ }
411
+ /**
412
+ * Generate a compliance report for discovered fields.
413
+ */
414
+ function generateComplianceReport(prorm, options = {}) {
415
+ const results = scanAllModels(prorm, options);
416
+ const byFramework = {
417
+ GDPR: 0,
418
+ HIPAA: 0,
419
+ PCI_DSS: 0,
420
+ APPI: 0,
421
+ PIPL: 0,
422
+ LGPD: 0,
423
+ CCPA: 0,
424
+ NIST: 0,
425
+ ISO: 0,
426
+ };
427
+ const byType = {
428
+ SSN: 0,
429
+ CREDIT_CARD: 0,
430
+ EMAIL: 0,
431
+ PHONE: 0,
432
+ HEALTH_ID: 0,
433
+ DRIVERS_LICENSE: 0,
434
+ PASSPORT: 0,
435
+ BANK_ACCOUNT: 0,
436
+ IBAN: 0,
437
+ DATE_OF_BIRTH: 0,
438
+ IP_ADDRESS: 0,
439
+ BIOMETRIC: 0,
440
+ MEDICAL_RECORD: 0,
441
+ PRESCRIPTION: 0,
442
+ INSURANCE_ID: 0,
443
+ NATIONAL_ID: 0,
444
+ };
445
+ let totalSensitiveFields = 0;
446
+ for (const result of results) {
447
+ totalSensitiveFields += result.fields.length;
448
+ for (const field of result.fields) {
449
+ for (const fw of field.frameworks) {
450
+ byFramework[fw]++;
451
+ }
452
+ byType[field.type]++;
453
+ }
454
+ }
455
+ return {
456
+ summary: {
457
+ totalModels: results.length,
458
+ totalSensitiveFields,
459
+ byFramework,
460
+ byType,
461
+ },
462
+ models: results,
463
+ };
464
+ }
465
+ // ==================== Class Export ====================
466
+ class SensitiveDataDiscovery {
467
+ }
468
+ exports.SensitiveDataDiscovery = SensitiveDataDiscovery;
469
+ SensitiveDataDiscovery.scan = scanModel;
470
+ SensitiveDataDiscovery.scanAll = scanAllModels;
471
+ SensitiveDataDiscovery.getDiscoveredFields = getDiscoveredFieldsForModel;
472
+ SensitiveDataDiscovery.autoProtect = autoProtectModel;
473
+ SensitiveDataDiscovery.registerPattern = registerPattern;
474
+ SensitiveDataDiscovery.unregisterPattern = unregisterPattern;
475
+ SensitiveDataDiscovery.getPatterns = getPatterns;
476
+ SensitiveDataDiscovery.generateComplianceReport = generateComplianceReport;