fraiseql-confiture 0.3.7__cp311-cp311-macosx_11_0_arm64.whl

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 (124) hide show
  1. confiture/__init__.py +48 -0
  2. confiture/_core.cpython-311-darwin.so +0 -0
  3. confiture/cli/__init__.py +0 -0
  4. confiture/cli/dry_run.py +116 -0
  5. confiture/cli/lint_formatter.py +193 -0
  6. confiture/cli/main.py +1893 -0
  7. confiture/config/__init__.py +0 -0
  8. confiture/config/environment.py +263 -0
  9. confiture/core/__init__.py +51 -0
  10. confiture/core/anonymization/__init__.py +0 -0
  11. confiture/core/anonymization/audit.py +485 -0
  12. confiture/core/anonymization/benchmarking.py +372 -0
  13. confiture/core/anonymization/breach_notification.py +652 -0
  14. confiture/core/anonymization/compliance.py +617 -0
  15. confiture/core/anonymization/composer.py +298 -0
  16. confiture/core/anonymization/data_subject_rights.py +669 -0
  17. confiture/core/anonymization/factory.py +319 -0
  18. confiture/core/anonymization/governance.py +737 -0
  19. confiture/core/anonymization/performance.py +1092 -0
  20. confiture/core/anonymization/profile.py +284 -0
  21. confiture/core/anonymization/registry.py +195 -0
  22. confiture/core/anonymization/security/kms_manager.py +547 -0
  23. confiture/core/anonymization/security/lineage.py +888 -0
  24. confiture/core/anonymization/security/token_store.py +686 -0
  25. confiture/core/anonymization/strategies/__init__.py +41 -0
  26. confiture/core/anonymization/strategies/address.py +359 -0
  27. confiture/core/anonymization/strategies/credit_card.py +374 -0
  28. confiture/core/anonymization/strategies/custom.py +161 -0
  29. confiture/core/anonymization/strategies/date.py +218 -0
  30. confiture/core/anonymization/strategies/differential_privacy.py +398 -0
  31. confiture/core/anonymization/strategies/email.py +141 -0
  32. confiture/core/anonymization/strategies/format_preserving_encryption.py +310 -0
  33. confiture/core/anonymization/strategies/hash.py +150 -0
  34. confiture/core/anonymization/strategies/ip_address.py +235 -0
  35. confiture/core/anonymization/strategies/masking_retention.py +252 -0
  36. confiture/core/anonymization/strategies/name.py +298 -0
  37. confiture/core/anonymization/strategies/phone.py +119 -0
  38. confiture/core/anonymization/strategies/preserve.py +85 -0
  39. confiture/core/anonymization/strategies/redact.py +101 -0
  40. confiture/core/anonymization/strategies/salted_hashing.py +322 -0
  41. confiture/core/anonymization/strategies/text_redaction.py +183 -0
  42. confiture/core/anonymization/strategies/tokenization.py +334 -0
  43. confiture/core/anonymization/strategy.py +241 -0
  44. confiture/core/anonymization/syncer_audit.py +357 -0
  45. confiture/core/blue_green.py +683 -0
  46. confiture/core/builder.py +500 -0
  47. confiture/core/checksum.py +358 -0
  48. confiture/core/connection.py +184 -0
  49. confiture/core/differ.py +522 -0
  50. confiture/core/drift.py +564 -0
  51. confiture/core/dry_run.py +182 -0
  52. confiture/core/health.py +313 -0
  53. confiture/core/hooks/__init__.py +87 -0
  54. confiture/core/hooks/base.py +232 -0
  55. confiture/core/hooks/context.py +146 -0
  56. confiture/core/hooks/execution_strategies.py +57 -0
  57. confiture/core/hooks/observability.py +220 -0
  58. confiture/core/hooks/phases.py +53 -0
  59. confiture/core/hooks/registry.py +295 -0
  60. confiture/core/large_tables.py +775 -0
  61. confiture/core/linting/__init__.py +70 -0
  62. confiture/core/linting/composer.py +192 -0
  63. confiture/core/linting/libraries/__init__.py +17 -0
  64. confiture/core/linting/libraries/gdpr.py +168 -0
  65. confiture/core/linting/libraries/general.py +184 -0
  66. confiture/core/linting/libraries/hipaa.py +144 -0
  67. confiture/core/linting/libraries/pci_dss.py +104 -0
  68. confiture/core/linting/libraries/sox.py +120 -0
  69. confiture/core/linting/schema_linter.py +491 -0
  70. confiture/core/linting/versioning.py +151 -0
  71. confiture/core/locking.py +389 -0
  72. confiture/core/migration_generator.py +298 -0
  73. confiture/core/migrator.py +882 -0
  74. confiture/core/observability/__init__.py +44 -0
  75. confiture/core/observability/audit.py +323 -0
  76. confiture/core/observability/logging.py +187 -0
  77. confiture/core/observability/metrics.py +174 -0
  78. confiture/core/observability/tracing.py +192 -0
  79. confiture/core/pg_version.py +418 -0
  80. confiture/core/pool.py +406 -0
  81. confiture/core/risk/__init__.py +39 -0
  82. confiture/core/risk/predictor.py +188 -0
  83. confiture/core/risk/scoring.py +248 -0
  84. confiture/core/rollback_generator.py +388 -0
  85. confiture/core/schema_analyzer.py +769 -0
  86. confiture/core/schema_to_schema.py +590 -0
  87. confiture/core/security/__init__.py +32 -0
  88. confiture/core/security/logging.py +201 -0
  89. confiture/core/security/validation.py +416 -0
  90. confiture/core/signals.py +371 -0
  91. confiture/core/syncer.py +540 -0
  92. confiture/exceptions.py +192 -0
  93. confiture/integrations/__init__.py +0 -0
  94. confiture/models/__init__.py +24 -0
  95. confiture/models/lint.py +193 -0
  96. confiture/models/migration.py +265 -0
  97. confiture/models/schema.py +203 -0
  98. confiture/models/sql_file_migration.py +225 -0
  99. confiture/scenarios/__init__.py +36 -0
  100. confiture/scenarios/compliance.py +586 -0
  101. confiture/scenarios/ecommerce.py +199 -0
  102. confiture/scenarios/financial.py +253 -0
  103. confiture/scenarios/healthcare.py +315 -0
  104. confiture/scenarios/multi_tenant.py +340 -0
  105. confiture/scenarios/saas.py +295 -0
  106. confiture/testing/FRAMEWORK_API.md +722 -0
  107. confiture/testing/__init__.py +100 -0
  108. confiture/testing/fixtures/__init__.py +11 -0
  109. confiture/testing/fixtures/data_validator.py +229 -0
  110. confiture/testing/fixtures/migration_runner.py +167 -0
  111. confiture/testing/fixtures/schema_snapshotter.py +352 -0
  112. confiture/testing/frameworks/__init__.py +10 -0
  113. confiture/testing/frameworks/mutation.py +587 -0
  114. confiture/testing/frameworks/performance.py +479 -0
  115. confiture/testing/loader.py +225 -0
  116. confiture/testing/pytest/__init__.py +38 -0
  117. confiture/testing/pytest_plugin.py +190 -0
  118. confiture/testing/sandbox.py +304 -0
  119. confiture/testing/utils/__init__.py +0 -0
  120. fraiseql_confiture-0.3.7.dist-info/METADATA +438 -0
  121. fraiseql_confiture-0.3.7.dist-info/RECORD +124 -0
  122. fraiseql_confiture-0.3.7.dist-info/WHEEL +4 -0
  123. fraiseql_confiture-0.3.7.dist-info/entry_points.txt +4 -0
  124. fraiseql_confiture-0.3.7.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,438 @@
1
+ Metadata-Version: 2.4
2
+ Name: fraiseql-confiture
3
+ Version: 0.3.7
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.11
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Topic :: Database
12
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
+ Requires-Dist: typer>=0.12.0
14
+ Requires-Dist: rich>=13.7.0
15
+ Requires-Dist: pydantic>=2.5.0
16
+ Requires-Dist: pyyaml>=6.0.1
17
+ Requires-Dist: psycopg[binary,pool]>=3.1.0
18
+ Requires-Dist: sqlparse>=0.5.0
19
+ Requires-Dist: cryptography>=42.0.0
20
+ Requires-Dist: pytest>=8.0.0 ; extra == 'testing'
21
+ Requires-Dist: pytest-asyncio>=0.23.0 ; extra == 'testing'
22
+ Requires-Dist: pytest-cov>=4.1.0 ; extra == 'testing'
23
+ Requires-Dist: pytest-json-report>=1.5.0 ; extra == 'testing'
24
+ Requires-Dist: pytest>=8.0.0 ; extra == 'dev'
25
+ Requires-Dist: pytest-asyncio>=0.23.0 ; extra == 'dev'
26
+ Requires-Dist: pytest-cov>=4.1.0 ; extra == 'dev'
27
+ Requires-Dist: pytest-watch>=4.2.0 ; extra == 'dev'
28
+ Requires-Dist: pytest-json-report>=1.5.0 ; extra == 'dev'
29
+ Requires-Dist: ruff>=0.6.0 ; extra == 'dev'
30
+ Requires-Dist: ty>=0.0.7 ; extra == 'dev'
31
+ Requires-Dist: maturin>=1.7.0 ; extra == 'dev'
32
+ Provides-Extra: testing
33
+ Provides-Extra: dev
34
+ Provides-Extra: fraiseql
35
+ License-File: LICENSE
36
+ Summary: PostgreSQL migrations, sweetly done 🍓
37
+ Keywords: postgresql,migration,database,schema,ddl
38
+ Home-Page: https://github.com/fraiseql/confiture
39
+ Author-email: evoludigit <lionel.hamayon@evolution-digitale.fr>
40
+ License: MIT
41
+ Requires-Python: >=3.11
42
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
43
+ Project-URL: Homepage, https://github.com/fraiseql/confiture
44
+ Project-URL: Documentation, https://github.com/fraiseql/confiture
45
+ Project-URL: Repository, https://github.com/fraiseql/confiture
46
+ Project-URL: Issues, https://github.com/fraiseql/confiture/issues
47
+ Project-URL: FraiseQL, https://github.com/fraiseql/fraiseql
48
+
49
+ # Confiture 🍓
50
+
51
+ **PostgreSQL migrations, sweetly done**
52
+
53
+ Confiture is the official migration tool for [FraiseQL](https://github.com/fraiseql/fraiseql), designed with a **build-from-scratch philosophy** and **4 migration strategies** to handle every scenario from local development to zero-downtime production deployments.
54
+
55
+ > **Part of the FraiseQL ecosystem** - While Confiture works standalone for any PostgreSQL project, it's designed to integrate seamlessly with FraiseQL's GraphQL-first approach.
56
+
57
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
58
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
59
+ [![PostgreSQL 12+](https://img.shields.io/badge/PostgreSQL-12%2B-blue?logo=postgresql&logoColor=white)](https://www.postgresql.org/)
60
+ [![CI](https://img.shields.io/github/actions/workflow/status/fraiseql/confiture/ci.yml?branch=main&label=CI&logo=github)](https://github.com/fraiseql/confiture/actions/workflows/ci.yml)
61
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
62
+ [![Made with Rust](https://img.shields.io/badge/Made%20with-Rust-orange?logo=rust)](https://www.rust-lang.org/)
63
+ [![Part of FraiseQL](https://img.shields.io/badge/Part%20of-FraiseQL-ff69b4)](https://github.com/fraiseql/fraiseql)
64
+ [![Status: Beta](https://img.shields.io/badge/status-beta-yellow)](https://github.com/fraiseql/confiture)
65
+
66
+ ---
67
+
68
+ ## 🍓 Part of the FraiseQL Ecosystem
69
+
70
+ **confiture** accelerates PostgreSQL schema evolution across the FraiseQL stack:
71
+
72
+ ### **Server Stack (PostgreSQL + Python/Rust)**
73
+
74
+ | Tool | Purpose | Status | Performance Gain |
75
+ |------|---------|--------|------------------|
76
+ | **[pg_tviews](https://github.com/fraiseql/pg_tviews)** | Incremental materialized views | Beta | **100-500× faster** |
77
+ | **[jsonb_delta](https://github.com/evoludigit/jsonb_delta)** | JSONB surgical updates | Stable | **2-7× faster** |
78
+ | **[pgGit](https://pggit.dev)** | Database version control | Stable | Git for databases |
79
+ | **[confiture](https://github.com/fraiseql/confiture)** | PostgreSQL migrations | **Beta** | **300-600× faster** (theoretical) |
80
+ | **[fraiseql](https://fraiseql.dev)** | GraphQL framework | Stable | **7-10× faster** |
81
+ | **[fraiseql-data](https://github.com/fraiseql/fraiseql-seed)** | Seed data generation | Phase 6 | Auto-dependency resolution |
82
+
83
+ ### **Client Libraries (TypeScript/JavaScript)**
84
+
85
+ | Library | Purpose | Framework Support |
86
+ |---------|---------|-------------------|
87
+ | **[graphql-cascade](https://github.com/graphql-cascade/graphql-cascade)** | Automatic cache invalidation | Apollo, React Query, Relay, URQL |
88
+
89
+ **How confiture fits:**
90
+ - **Build from DDL** → Fresh DB in <1s for **fraiseql** GraphQL testing
91
+ - **pgGit** automatically tracks confiture migrations
92
+ - Manage **pg_tviews** schema evolution with 4 migration strategies
93
+ - **fraiseql-data** seeds the schema confiture built
94
+
95
+ **Intended workflow:**
96
+ ```bash
97
+ # Build schema from DDL files
98
+ confiture build --env test
99
+
100
+ # Seed test data
101
+ fraiseql-data add tb_user --count 100
102
+
103
+ # Run GraphQL tests
104
+ pytest
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Why Confiture?
110
+
111
+ ### The Problem with Migration History
112
+
113
+ Traditional migration tools (Alembic, Django migrations, Flyway) use **migration history replay**: every time you build a database, the tool executes every migration file in order. This works, but it's **slow and brittle**:
114
+
115
+ - **Slow**: Fresh database builds take 5-10 minutes (replaying hundreds of operations)
116
+ - **Brittle**: One broken migration breaks everything - your database history is fragile
117
+ - **Complicated**: Developers maintain two things: current schema AND migration history
118
+ - **Messy**: Technical debt accumulates as migrations pile up over months/years
119
+
120
+ ### The Confiture Approach
121
+
122
+ Confiture flips the model: **DDL source files are the single source of truth**. To build a database:
123
+
124
+ 1. Read all `.sql` files in `db/schema/`
125
+ 2. Execute them once (in order)
126
+ 3. Done ✅
127
+
128
+ No migration history to replay. No accumulated technical debt. Just your actual, current schema. **Fresh databases in <1 second.**
129
+
130
+ ### Intended Advantages Over Alembic
131
+
132
+ | Feature | Confiture | Alembic | Notes |
133
+ |---------|-----------|---------|-------|
134
+ | **Fresh DB setup** | Direct DDL execution | Migration replay | Theoretically faster |
135
+ | **Zero-downtime migrations** | Via FDW (planned) | Not built-in | Not yet production-tested |
136
+ | **Production data sync** | Built-in (with PII anonymization) | Not available | Not yet production-tested |
137
+ | **Schema diffs** | Auto-generated | Manual | Implemented |
138
+ | **Conceptual simplicity** | DDL-first | Migration-first | Different philosophy |
139
+
140
+ ### What's Implemented
141
+
142
+ - ✅ **4 migration strategies** (Build from DDL, ALTER, Production Sync, FDW)
143
+ - ✅ **Python + optional Rust extension**
144
+ - ✅ **PII anonymization strategies**
145
+ - ✅ **Comprehensive test suite** (3,200+ tests)
146
+ - ⚠️ **Not yet used in production** - Beta software
147
+
148
+ ---
149
+
150
+ ## The Four Mediums
151
+
152
+ ### 1️⃣ Build from DDL
153
+ ```bash
154
+ confiture build --env production
155
+ ```
156
+ Build fresh database from `db/schema/` DDL files in <1 second.
157
+
158
+ ### 2️⃣ Incremental Migrations (ALTER)
159
+ ```bash
160
+ confiture migrate up
161
+ ```
162
+ Apply migrations to existing database (simple schema changes).
163
+
164
+ ### 3️⃣ Production Data Sync
165
+ ```bash
166
+ confiture sync --from production --anonymize users.email
167
+ ```
168
+ Copy production data to local/staging with PII anonymization.
169
+
170
+ ### 4️⃣ Schema-to-Schema Migration (Zero-Downtime)
171
+ ```bash
172
+ confiture migrate schema-to-schema --strategy fdw
173
+ ```
174
+ Complex migrations via FDW with 0-5 second downtime.
175
+
176
+ ---
177
+
178
+ ## Quick Start
179
+
180
+ ### Installation
181
+
182
+ ```bash
183
+ pip install fraiseql-confiture
184
+
185
+ # Or with FraiseQL integration
186
+ pip install fraiseql-confiture[fraiseql]
187
+ ```
188
+
189
+ ### Initialize Project
190
+
191
+ ```bash
192
+ confiture init
193
+ ```
194
+
195
+ Creates:
196
+ ```
197
+ db/
198
+ ├── schema/ # DDL: CREATE TABLE, views, functions
199
+ │ ├── 00_common/
200
+ │ ├── 10_tables/
201
+ │ └── 20_views/
202
+ ├── seeds/ # INSERT: Environment-specific test data
203
+ │ ├── common/
204
+ │ ├── development/
205
+ │ └── test/
206
+ ├── migrations/ # Generated migration files
207
+ └── environments/ # Environment configurations
208
+ ├── local.yaml
209
+ ├── test.yaml
210
+ └── production.yaml
211
+ ```
212
+
213
+ ### Build Schema
214
+
215
+ ```bash
216
+ # Build local database
217
+ confiture build --env local
218
+
219
+ # Build production schema
220
+ confiture build --env production
221
+ ```
222
+
223
+ ### Create Migration
224
+
225
+ ```bash
226
+ # Edit schema
227
+ vim db/schema/10_tables/users.sql
228
+
229
+ # Generate migration
230
+ confiture migrate generate --name "add_user_bio"
231
+
232
+ # Apply migration
233
+ confiture migrate up
234
+ ```
235
+
236
+ ### Test Migrations Before Applying (Dry-Run)
237
+
238
+ Analyze migrations without executing them:
239
+
240
+ ```bash
241
+ # Analyze pending migrations
242
+ confiture migrate up --dry-run
243
+
244
+ # Test in SAVEPOINT (guaranteed rollback)
245
+ confiture migrate up --dry-run-execute
246
+
247
+ # Save analysis to file
248
+ confiture migrate up --dry-run --format json --output report.json
249
+
250
+ # Analyze rollback impact
251
+ confiture migrate down --dry-run --steps 2
252
+ ```
253
+
254
+ For more details, see **[Dry-Run Guide](docs/guides/cli-dry-run.md)**.
255
+
256
+ ---
257
+
258
+ ## Documentation
259
+
260
+ ### User Guides
261
+
262
+ **Core Concepts**:
263
+ - **[Build from DDL](docs/guides/01-build-from-ddl.md)** - Execute DDL files directly
264
+ - **[Incremental Migrations](docs/guides/02-incremental-migrations.md)** - ALTER-based changes
265
+ - **[Production Data Sync](docs/guides/03-production-sync.md)** - Copy and anonymize data
266
+ - **[Zero-Downtime Migrations](docs/guides/04-schema-to-schema.md)** - Schema-to-schema via FDW
267
+ - **[Migration Decision Tree](docs/guides/migration-decision-tree.md)** - Choose the right strategy
268
+
269
+ **Advanced**:
270
+ - **[Dry-Run Mode](docs/guides/dry-run.md)** - Test migrations before applying
271
+ - **[Migration Hooks](docs/guides/hooks.md)** - Execute custom logic before/after migrations
272
+ - **[Anonymization](docs/guides/anonymization.md)** - PII data masking strategies
273
+ - **[Compliance](docs/guides/compliance.md)** - HIPAA, SOX, PCI-DSS, GDPR
274
+ - **[Integrations](docs/guides/integrations.md)** - Slack, GitHub Actions, monitoring
275
+
276
+ ### API Reference
277
+
278
+ - **[CLI Reference](docs/reference/cli.md)** - All commands documented
279
+ - **[Configuration](docs/reference/configuration.md)** - Environment configuration
280
+ - **[Schema Builder API](docs/api/builder.md)** - Building schemas programmatically
281
+ - **[Migrator API](docs/api/migrator.md)** - Migration execution
282
+ - **[Syncer API](docs/api/syncer.md)** - Production data sync
283
+ - **[Hook API](docs/api/hooks.md)** - Migration lifecycle hooks
284
+ - **[Anonymization API](docs/api/anonymization.md)** - PII data masking
285
+ - **[Linting API](docs/api/linting.md)** - Schema validation rules
286
+
287
+ ### Examples
288
+ - **[Examples Overview](examples/)** - Complete examples
289
+ - **[Basic Migration](examples/01-basic-migration/)** - Learn the fundamentals
290
+ - **[FraiseQL Integration](examples/02-fraiseql-integration/)** - GraphQL workflow
291
+ - **[Zero-Downtime](examples/03-zero-downtime-migration/)** - FDW-based migration
292
+ - **[Production Sync](examples/04-production-sync-anonymization/)** - PII anonymization
293
+
294
+ ---
295
+
296
+ ## Features
297
+
298
+ ### Core Migration System (Implemented)
299
+
300
+ - ✅ **Build from DDL** (Medium 1) - Execute DDL files directly
301
+ - ✅ **Incremental migrations** (Medium 2) - ALTER-based changes
302
+ - ✅ **Production data sync** (Medium 3) - Copy with PII anonymization
303
+ - ✅ **Zero-downtime migrations** (Medium 4) - Schema-to-schema via FDW
304
+
305
+ ### Additional Features (Implemented)
306
+
307
+ - ✅ Optional Rust extension for performance
308
+ - ✅ Schema diff detection with auto-generation
309
+ - ✅ CLI with rich terminal output
310
+ - ✅ Multi-environment configuration
311
+ - ✅ Migration hooks (pre/post execution)
312
+ - ✅ Schema linting with multiple rules
313
+ - ✅ PII anonymization strategies
314
+ - ✅ Dry-run mode for testing
315
+
316
+ ### Documentation (Comprehensive)
317
+
318
+ - ✅ User guides for all 4 migration strategies
319
+ - ✅ API reference documentation
320
+ - ✅ Integration guides (Slack, GitHub Actions, monitoring)
321
+ - ✅ Compliance guides (HIPAA, SOX, PCI-DSS, GDPR)
322
+
323
+ ---
324
+
325
+ ## Comparison
326
+
327
+ | Feature | Alembic | pgroll | **Confiture** |
328
+ |---------|---------|--------|---------------|
329
+ | **Philosophy** | Migration replay | Multi-version schema | **Build-from-DDL** |
330
+ | **Fresh DB setup** | Minutes | Minutes | **<1 second** |
331
+ | **Zero-downtime** | ❌ No | ✅ Yes | **✅ Yes (FDW)** |
332
+ | **Production sync** | ❌ No | ❌ No | **✅ Built-in** |
333
+ | **Language** | Python | Go | **Python + Rust** |
334
+
335
+ ---
336
+
337
+ ## Current Version
338
+
339
+ **v0.3.5**
340
+
341
+ > **⚠️ Beta Software**: Confiture has not yet been used in production. While the codebase includes comprehensive tests and documentation, real-world usage may reveal issues. Use with caution in production environments.
342
+
343
+ ### What's Implemented
344
+ - ✅ All 4 migration strategies (Build from DDL, ALTER, Production Sync, FDW)
345
+ - ✅ Comprehensive test suite (3,200+ tests passing)
346
+ - ✅ Documentation and guides
347
+ - ✅ Python 3.11, 3.12, 3.13 support
348
+ - ✅ Optional Rust extension
349
+ - ✅ Migration hooks, schema linting, anonymization strategies
350
+
351
+ ### What's NOT Validated
352
+ - ❌ Production usage (never deployed to production)
353
+ - ❌ Performance claims (benchmarks only, not real-world)
354
+ - ❌ Edge cases and failure recovery (not battle-tested)
355
+ - ❌ Large-scale data migrations (theoretical only)
356
+
357
+ ---
358
+
359
+ ## Contributing
360
+
361
+ Contributions welcome! We'd love your help making Confiture even better.
362
+
363
+ **Quick Start**:
364
+ ```bash
365
+ # Clone repository
366
+ git clone https://github.com/fraiseql/confiture.git
367
+ cd confiture
368
+
369
+ # Install dependencies (includes Rust build)
370
+ uv sync --all-extras
371
+
372
+ # Build Rust extension
373
+ uv run maturin develop
374
+
375
+ # Run tests
376
+ uv run pytest --cov=confiture
377
+
378
+ # Format code
379
+ uv run ruff format .
380
+
381
+ # Type checking
382
+ uv run mypy python/confiture/
383
+ ```
384
+
385
+ **Resources**:
386
+ - **[CONTRIBUTING.md](CONTRIBUTING.md)** - Contributing guidelines
387
+ - **[CLAUDE.md](CLAUDE.md)** - AI-assisted development guide
388
+ - **[PHASES.md](PHASES.md)** - Detailed roadmap
389
+
390
+ **What to contribute**:
391
+ - 🐛 Bug fixes
392
+ - ✨ New features
393
+ - 📖 Documentation improvements
394
+ - 💡 New examples
395
+ - 🧪 Test coverage improvements
396
+
397
+ ---
398
+
399
+ ## Author
400
+
401
+ **Vibe-engineered by [Lionel Hamayon](https://github.com/LionelHamayon)** 🍓
402
+
403
+ Confiture was crafted with care as the migration tool for the FraiseQL ecosystem, combining the elegance of Python with the performance of Rust, and the sweetness of strawberry jam.
404
+
405
+ ---
406
+
407
+ ## License
408
+
409
+ MIT License - see [LICENSE](LICENSE) for details.
410
+
411
+ Copyright (c) 2025 Lionel Hamayon
412
+
413
+ ---
414
+
415
+ ## Acknowledgments
416
+
417
+ - Inspired by printoptim_backend's build-from-scratch approach
418
+ - Built for [FraiseQL](https://github.com/fraiseql/fraiseql) GraphQL framework
419
+ - Influenced by pgroll, Alembic, and Reshape
420
+ - Developed with AI-assisted vibe engineering ✨
421
+
422
+ ---
423
+
424
+ ## FraiseQL Ecosystem
425
+
426
+ Confiture is part of the FraiseQL family:
427
+
428
+ - **[FraiseQL](https://github.com/fraiseql/fraiseql)** - Modern GraphQL framework for Python
429
+ - **[Confiture](https://github.com/fraiseql/confiture)** - PostgreSQL migration tool (you are here)
430
+
431
+ ---
432
+
433
+ *Making jam from strawberries, one migration at a time.* 🍓→🍯
434
+
435
+ *Vibe-engineered with ❤️ by Lionel Hamayon*
436
+
437
+ **[Documentation](https://github.com/fraiseql/confiture)** • **[GitHub](https://github.com/fraiseql/confiture)** • **[PyPI](https://pypi.org/project/fraiseql-confiture/)**
438
+
@@ -0,0 +1,124 @@
1
+ confiture/__init__.py,sha256=LMwp18NrWv1GCzVsi0KF2dcCOiXF7yrs9Zl1Oe5YoPM,1248
2
+ confiture/_core.cpython-311-darwin.so,sha256=2itUjdwAIVm8KJIShFdxPVSEXFvSGgOXjS77dud1gsk,439792
3
+ confiture/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ confiture/cli/dry_run.py,sha256=MshEjPZtmzMci5fLVLhlZmd-k-CimQPf4B9XLzf48ao,3426
5
+ confiture/cli/lint_formatter.py,sha256=H9p9xa3c_9UOImNhD5H5KjgNUH1GlL9NLaAVvLMS7qc,5668
6
+ confiture/cli/main.py,sha256=_ebUumc0lp2SBBXgha8KMrftwgKi_vGUFdpZhMuV_w4,67796
7
+ confiture/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ confiture/config/environment.py,sha256=tmNNecfPOs6ncsUuuJMNb6Ytl_rhO_6Q1E7oGQgI_lo,9143
9
+ confiture/core/__init__.py,sha256=aLSEZOabdDp3tpWUMm2bSukLad9IQaM4XcC5TC0VGrw,1076
10
+ confiture/core/anonymization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ confiture/core/anonymization/audit.py,sha256=imdrsXiZn8zoLUNKYbscWN0UkSlReiFkdaNaVlb20JU,16698
12
+ confiture/core/anonymization/benchmarking.py,sha256=qDjiNg4EkqGmHntRTpOd70kWOPnIkY_rjVoR7Fkzm9k,11662
13
+ confiture/core/anonymization/breach_notification.py,sha256=vPE2FByUAYw-Ql43c0DmBXNoYwbgfrjzIu551KLbuqI,21730
14
+ confiture/core/anonymization/compliance.py,sha256=zyIautpTeQtEToS6YsMDspaRc21vgIchuuCLjTTNxFI,21851
15
+ confiture/core/anonymization/composer.py,sha256=rNCZ_BZZgjlMIt2yezf3-V7JrMgaYQyAOUn7Ien2c6I,8972
16
+ confiture/core/anonymization/data_subject_rights.py,sha256=dOD7coq-2dG2v9j167oOEZoG9pzMz2J_lw_-DOCpuqw,21415
17
+ confiture/core/anonymization/factory.py,sha256=ZiJ3Nv49P7eQEMSeYqQ0QfNG6XiBBGTPpxMAaQBwEX4,10042
18
+ confiture/core/anonymization/governance.py,sha256=hUUoDIaM8QApCFpnlRh2uQtpGWkrqDz_3CpBkTE_1nY,22791
19
+ confiture/core/anonymization/performance.py,sha256=6J6Iuyx0vxW-rIGIcpFIMR_QJfTkhtdYHwxAqBcNMc8,35411
20
+ confiture/core/anonymization/profile.py,sha256=SPbLp9VyXUhxf-ca40wNgxIXusMcJM4gCDIiIDpJk38,8809
21
+ confiture/core/anonymization/registry.py,sha256=bnPSUM9kr4WNyGGEMHaF3Y-N9X5mfob9uolxd_r-z9I,5749
22
+ confiture/core/anonymization/security/kms_manager.py,sha256=4OJVDA0G-PRjLTkRXqWz8ErgpXZeD7kLqCTZHP-ZsFw,16040
23
+ confiture/core/anonymization/security/lineage.py,sha256=nQHBb5qo1lzfmBzPsS6_whZAVVUcq8esH6FjdIqDY1I,31570
24
+ confiture/core/anonymization/security/token_store.py,sha256=7tTsUwTfbhoCRyzS2captA3g5yB_D59tZXShe_7heUM,22871
25
+ confiture/core/anonymization/strategies/__init__.py,sha256=rqrnZQZ-fBWOPZIFX_T5fzqvCjf2aOtKKEsWda2hJ68,1717
26
+ confiture/core/anonymization/strategies/address.py,sha256=iv8OP-Tihju-8FX9I5PG_FSXRPtSO0h5HdG3RYrA_Wg,9429
27
+ confiture/core/anonymization/strategies/credit_card.py,sha256=z-u9AKVTxNyqeWVraosa_cxTduqJ6pt3W3aLwmDJCFo,12077
28
+ confiture/core/anonymization/strategies/custom.py,sha256=eJmH1KDWzTn_wNowIzCombOLq3obCMYVr_-IORR3O4Y,4687
29
+ confiture/core/anonymization/strategies/date.py,sha256=I5TA7gOgyHnR-C4lI8E-KvY2luGepeW-vJhyVyHvFVs,6788
30
+ confiture/core/anonymization/strategies/differential_privacy.py,sha256=bZ-mImlOrL29jhb01kuFz4R_oEWsJHU42pf3sCGxhgU,13244
31
+ confiture/core/anonymization/strategies/email.py,sha256=gfKyklZN13Zl6t3r3FRbOmttoqo51DQaTkIlYij_bjw,4351
32
+ confiture/core/anonymization/strategies/format_preserving_encryption.py,sha256=a4qOM3Enf2ZGdN52474HREQ9tEf3ZPhN-sT0HovMhCk,10232
33
+ confiture/core/anonymization/strategies/hash.py,sha256=9DL3fj4od9y2PRGdEfCxFo44aWxiUhi6TH0FJ_9wwbE,4751
34
+ confiture/core/anonymization/strategies/ip_address.py,sha256=puWs6NNE6FeLIrLJRc0pjqFX3NPT_H76pBVZzVoeC8U,7528
35
+ confiture/core/anonymization/strategies/masking_retention.py,sha256=ZnhuBYn5WbKFKnm6wIRKhznG-gzVRxZZOOpblFiLUIc,8274
36
+ confiture/core/anonymization/strategies/name.py,sha256=jmM-waL4NZ6sNY4aOiYn8WFyhMt5N73VRhhnkavlRdc,7277
37
+ confiture/core/anonymization/strategies/phone.py,sha256=_i1hHbdWD6pS3qXYVmccg0oImybVe4SOmXyPJq1KIXU,3597
38
+ confiture/core/anonymization/strategies/preserve.py,sha256=XRRAs0FTlIZlvnWL25ZGDBx_Et1p6IFwoxpOdCMGVUM,2193
39
+ confiture/core/anonymization/strategies/redact.py,sha256=8j3VBLQF9Q0ZfZKYQMJixwKaOgsKQXdKBhRprsMinFs,2999
40
+ confiture/core/anonymization/strategies/salted_hashing.py,sha256=3fZ9Lv2cRErI2NSyar5Yu3FmiOQb5Rircs1UjVkeZx8,10649
41
+ confiture/core/anonymization/strategies/text_redaction.py,sha256=JUnf2BVOCFqMeHfCdHzJOprnRy8_TrGXCj9BNGWE3Ok,5952
42
+ confiture/core/anonymization/strategies/tokenization.py,sha256=DdqCtjS8BVin6u4lX0fz_qj5i5od0kMymF6Rf-5QmZ4,12266
43
+ confiture/core/anonymization/strategy.py,sha256=KuiYH6T4X5-JQGRv_lFgSqJ_miBHMFrD07DiuosJSzw,7858
44
+ confiture/core/anonymization/syncer_audit.py,sha256=qDgVadUOdKW9PSlugP9Z5yWQkM1S3lGQmNjbSIekDgY,11449
45
+ confiture/core/blue_green.py,sha256=4BcYxdYKOUAKGfahLsAI5PxkHyGbsb0xRoRbFgx5GdY,23449
46
+ confiture/core/builder.py,sha256=EEq1zVG7ozfp1k9F7F4akX6hsl8Z4Sk5iFACqaGfIYM,18127
47
+ confiture/core/checksum.py,sha256=1PhiZltVKaG1oK-A1BiLIDDf8EN_TzSGsu-aWWHIxOs,11096
48
+ confiture/core/connection.py,sha256=7LFuqNkrHcUhso-MCEclb5BGJ_HDto0eTsgM6TmFgPg,5973
49
+ confiture/core/differ.py,sha256=etICDfHY9wOvqxFkiwuVIbHS7N8gmKG04qhbfWtB2t0,18024
50
+ confiture/core/drift.py,sha256=SGY76Dk5bXOMsv3W54_fkmV9I2n46021QNvoHvWeJpY,18938
51
+ confiture/core/dry_run.py,sha256=E1n-B391i2weik3mlIyZCwK3iyRcmNqzgJYPGjOSHr4,5640
52
+ confiture/core/health.py,sha256=j8kZBg8OJBQGNw398tr0fpCuDg1J_FK7eOcqLAxGR-4,9842
53
+ confiture/core/hooks/__init__.py,sha256=3QHRvTT6MOMUbeWY81SWHWoHoxQniyTxJ8oZ49Vi-ec,2003
54
+ confiture/core/hooks/base.py,sha256=CXifTRddrk8htgqbpyBKISHXheK-nHHn0Skn3_rkNB0,7084
55
+ confiture/core/hooks/context.py,sha256=ZHVV_vFkHWUthjW2kEwTlrKy0hSjAe4ArQz5ZB52WyM,4253
56
+ confiture/core/hooks/execution_strategies.py,sha256=LZqe_pXle1ZZwwgP6IzdFQyNS7aRNA2xB3J5Rk16RAQ,1993
57
+ confiture/core/hooks/observability.py,sha256=mtRCR42VTCUQhx8DZic0-wKuWJTgzz3KXMxgIuLbWWI,6938
58
+ confiture/core/hooks/phases.py,sha256=KoTKLyJECRpzxA1IrmySb034TiHWldZ4J_z1Z8Ug4v4,1818
59
+ confiture/core/hooks/registry.py,sha256=G5Z2pH9IloRO-K5lMJDuvKuexZ1XNtdHnR5DtM2vwd4,11075
60
+ confiture/core/large_tables.py,sha256=wwv9JT0a8Xr7SK916zA9B300G5f-GMVFKHw4-6nDY_M,25669
61
+ confiture/core/linting/__init__.py,sha256=pbHXH6hVB56vEdvDh4nmQPlgZm68Y6kkTEnSazrx87k,1312
62
+ confiture/core/linting/composer.py,sha256=zwXzHuewCMtVRP5fBOQZPAQpWtCZC_8MEaOvCJTxifw,6436
63
+ confiture/core/linting/libraries/__init__.py,sha256=gQGq0paX05pfdHI3h7WQpACrLSMsyRcjLcfkbqyDu-w,367
64
+ confiture/core/linting/libraries/gdpr.py,sha256=5kcgSCYYt7AsIU8f8tZpbd7p4vOGeETsN3BDbJ9xy5I,6400
65
+ confiture/core/linting/libraries/general.py,sha256=yLzQGd4HVYttCDqcai1etFB8ynkyPnFc5WGs61S-c6Q,7145
66
+ confiture/core/linting/libraries/hipaa.py,sha256=2f1AX484QN7pufl9K_8PTtyygMqk2AKSW4Q_Ei8ii8o,5420
67
+ confiture/core/linting/libraries/pci_dss.py,sha256=Pp-7bsGvFqNNlXTBPvlU9LdUnzv1Jvt7xfYyjSWkz6I,3957
68
+ confiture/core/linting/libraries/sox.py,sha256=gHi8HGd9X21gzlYJnpVhso-YcN3-TXoPWLOTYLLULu8,4455
69
+ confiture/core/linting/schema_linter.py,sha256=3dU3qTXzLyER5eW4PiWGzm6gJL3u2mzEojpuk8nKwWg,16694
70
+ confiture/core/linting/versioning.py,sha256=LtRhSZXFRFqnQwgHlwFKecIuv48p2UmOXOss9eHE52g,4164
71
+ confiture/core/locking.py,sha256=ItGWwdmwy3E46XWIp71pC9qB7Fcj1WW5tDuTcuBaNok,12950
72
+ confiture/core/migration_generator.py,sha256=-vOzZO8ENjJqDUOaNsE6s28SgxQXP9NYDwgV_7RiYW4,9732
73
+ confiture/core/migrator.py,sha256=rLOEGT2gS3i9putY_z-twc2J7LafwN6J47ojOuor_48,32979
74
+ confiture/core/observability/__init__.py,sha256=QbaY-idsiyAqdKplU10bbOgrUFlTlTQ1H-WxksaFgf4,881
75
+ confiture/core/observability/audit.py,sha256=YV5yRReRVqeAxJouBsWeYf1R216XVl8UAFpOZ-XXd-4,9862
76
+ confiture/core/observability/logging.py,sha256=X5ueS4jqpERFyYaqfohLY4wMyy9nIi7K2tmo4IoPMi0,5511
77
+ confiture/core/observability/metrics.py,sha256=uaPYsCys-l7ctOPhgiy_StU3A-7JRvDLrAHYPIQKDdo,5317
78
+ confiture/core/observability/tracing.py,sha256=WcjFJ8dV9pK68aNetP5hWYz5aRxkc918uKYqNHD_ccI,5525
79
+ confiture/core/pg_version.py,sha256=RcXqTzWBtVAw2DwK-PX8S1pdupve4ogRo8KBEs4lbjk,12003
80
+ confiture/core/pool.py,sha256=Wt6N1Y7Hgkap010GCQ9y9jzyQzCLPNEuUW0fgtLS2l8,14184
81
+ confiture/core/risk/__init__.py,sha256=kCfy8PGiW_4hRiIC8_ZeTTqnB-XigLxcQnXnilPCKEg,753
82
+ confiture/core/risk/predictor.py,sha256=k3s7iW0s2OMLYGJimrgR9llYoEuZx5BGM7mlcQ017P4,6261
83
+ confiture/core/risk/scoring.py,sha256=TH2wafs3DOOdl72EcyUm26Zlt6AnntlN5x0qbXtg3yo,7304
84
+ confiture/core/rollback_generator.py,sha256=SzVMimCgs4NlnO1M93TOEY-lsMk7NMlkZ60LxyzMYB4,12600
85
+ confiture/core/schema_analyzer.py,sha256=qeGYUUXlx9vzpI4_PHhYOE5U1fqNy3rYflass5oUG6Q,27148
86
+ confiture/core/schema_to_schema.py,sha256=ug4RriePVKnsfbyf3QZBFsWbwP4jwX7EojGgWEMGeYs,22242
87
+ confiture/core/security/__init__.py,sha256=XSE2LDzsu-ejUtAvCT2TaHT4mh0NXW9nqWSPQoEpn4k,818
88
+ confiture/core/security/logging.py,sha256=9C6vrNa00RTAEr58fi8ayUQgLBsB9tjED4NVqYH_xdM,6202
89
+ confiture/core/security/validation.py,sha256=RTC4xTwI961y0JmPfOZcY0kIWYXzBtXjsH5HMyGMd6k,12220
90
+ confiture/core/signals.py,sha256=u5oIlbqrbMsb6LUctBs39-HDuyR2S6A8AsihMIdq9a8,11628
91
+ confiture/core/syncer.py,sha256=J8w6kTRG3Jdi7s35LtSKqDoL3rgtRj1c3Lpe0v5BYiE,18398
92
+ confiture/exceptions.py,sha256=WbXW7JWhNNeztKVFygXTfUCAlGm6OaUYBSG42DKFNes,4741
93
+ confiture/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
+ confiture/models/__init__.py,sha256=e4GhGY5RVf0r9pP74fTCYn-YAthLAqkgoXxxyfSKo3Y,710
95
+ confiture/models/lint.py,sha256=YEgBnAruub33dAGhU10G4M3DT5JjoZ4VdkqjjP1_yAE,5896
96
+ confiture/models/migration.py,sha256=mY3g-8sI_B_-EnbYA3zSRBhix3mRpDgWMynM6EK8l_U,9625
97
+ confiture/models/schema.py,sha256=9zQzyyw35HR0T1b0T9hI9xoripdTeWLDFTnO_ibcrMI,5909
98
+ confiture/models/sql_file_migration.py,sha256=RmKa-MIVY01X6kqFmQQbM_HQpMErUXU-zXkvgJi8sJM,7354
99
+ confiture/scenarios/__init__.py,sha256=PcOvisGBkrP4IAlVGmvM5hQlwvwmtqkBMhWQPos03zI,1255
100
+ confiture/scenarios/compliance.py,sha256=yGm5nk-v-6mRt3wDOwQoTYfT5mlceSs0ZhZLiB3oK1g,20562
101
+ confiture/scenarios/ecommerce.py,sha256=cwcg3149gDeiTiZ56AtXtr2XImKBcu6zWwq_hi6FlTs,6809
102
+ confiture/scenarios/financial.py,sha256=j7GmWvNAKhBLZoCbOa7jnfMNWEVUjE7xj5P71LpLw2w,9445
103
+ confiture/scenarios/healthcare.py,sha256=qjJUPJ38WnHXM7kbxRsrD4r7QeuzGn8zrL50WFc6Jl8,12106
104
+ confiture/scenarios/multi_tenant.py,sha256=Td96qlAq_RhDU-2e0nlNMYlghfvkK5hi-VB_HPXT6Bs,12573
105
+ confiture/scenarios/saas.py,sha256=bQpnILxO59axDnZ3v2esAECtYJh5Ae3E7LiPGyTaicw,11150
106
+ confiture/testing/FRAMEWORK_API.md,sha256=NQSi5Vr3OXuygF2_BrWy0-jYOgA-FywgnVR-YzDeZYM,18997
107
+ confiture/testing/__init__.py,sha256=8NNaoRBnMEveL5uMjW4hVP_QDylqibJD4LnhQ3G45J4,2670
108
+ confiture/testing/fixtures/__init__.py,sha256=F5ei8MAZMwQUqUcOTa85pn8oZkuuV7h5eycDG-uWRss,368
109
+ confiture/testing/fixtures/data_validator.py,sha256=R6zi8DbXARREuriYf3piaNqdS7jvFKFWDuNO4D6F6Ac,7556
110
+ confiture/testing/fixtures/migration_runner.py,sha256=okC-x3j414HUbtURD0e3wvjyCySs582xtHi3HkZDcKw,5385
111
+ confiture/testing/fixtures/schema_snapshotter.py,sha256=_J5cx_QtQT36ttiRcAoaxKGOiwEYmgBnSdPdXEDhyiE,11917
112
+ confiture/testing/frameworks/__init__.py,sha256=0JMwqi2dRYUo0p8VlOEmx8czpk9m7ZKxgxCC4jEhMMM,324
113
+ confiture/testing/frameworks/mutation.py,sha256=1pHoWhAD-D6VT4thBtYd1Gc_L0wRAKh0Nbkpni74tv0,21611
114
+ confiture/testing/frameworks/performance.py,sha256=L56CMWM-gEubY54tyf0a3KG8_AY3nM7edeCotyKaQZ4,17214
115
+ confiture/testing/loader.py,sha256=F3UMFXu5Dt3dH3_1K5WwF6cxyQaroLuIa1e21VuslxA,8046
116
+ confiture/testing/pytest/__init__.py,sha256=oES2G47QamMsbh8pSy75bPQXEL0sqAVKNWTJ90aFmEE,1082
117
+ confiture/testing/pytest_plugin.py,sha256=5vl_J_2tHLpkvJ0AZwmuky_A3VgbLIJibp4I1GiXFB0,5852
118
+ confiture/testing/sandbox.py,sha256=LEmuJdgmxun4n-OlnBbbPkX7eJQ13hjl06jyCp4egRc,10586
119
+ confiture/testing/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
120
+ fraiseql_confiture-0.3.7.dist-info/METADATA,sha256=TlSea1qnWm7REk9_hREb8woRkeDiNEHsh4EzRpoReTc,15381
121
+ fraiseql_confiture-0.3.7.dist-info/WHEEL,sha256=dewdenAwp3PDth0u4HpQhcjieEs1_hiwRbm3WvCuoaI,104
122
+ fraiseql_confiture-0.3.7.dist-info/entry_points.txt,sha256=qJqykNiu9FrgwslE6NEHWJWf5ZVItSN4mFg_EtSBnRQ,104
123
+ fraiseql_confiture-0.3.7.dist-info/licenses/LICENSE,sha256=c6fKI61h1Rn-8ZkldOQxeyxEQYfzjpXpu_HgVjSu1ZI,1071
124
+ fraiseql_confiture-0.3.7.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.9.6)
3
+ Root-Is-Purelib: false
4
+ Tag: cp311-cp311-macosx_11_0_arm64
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ confiture=confiture.cli.main:app
3
+ [pytest11]
4
+ confiture=confiture.testing.pytest_plugin
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Lionel Hamayon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.