strapi-kit 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: strapi-kit
3
- Version: 0.0.2
3
+ Version: 0.0.4
4
4
  Summary: A modern Python client for Strapi CMS with import/export capabilities
5
5
  Project-URL: Homepage, https://github.com/mehdizare/strapi-kit
6
6
  Project-URL: Documentation, https://mehdizare.github.io/strapi-kit/
@@ -61,6 +61,7 @@ A modern Python client for Strapi CMS with comprehensive import/export capabilit
61
61
  - 🔒 **Type Safe**: Built with Pydantic for robust data validation and type safety
62
62
  - 🔄 **Import/Export**: Comprehensive backup/restore and data migration tools
63
63
  - 🔁 **Smart Retry**: Automatic retry with exponential backoff for transient failures
64
+ - 🔍 **Schema Introspection**: Content-Type Builder API support for schema discovery
64
65
  - 📦 **Modern Python**: Built for Python 3.12+ with full type hints
65
66
 
66
67
  ## Installation
@@ -654,6 +655,144 @@ asyncio.run(main())
654
655
  - Update metadata without re-uploading
655
656
  - Full support for both sync and async
656
657
 
658
+ ### Content-Type Builder API
659
+
660
+ Query Strapi's Content-Type Builder to discover schemas, content types, and components:
661
+
662
+ ```python
663
+ from strapi_kit import SyncClient, StrapiConfig
664
+
665
+ config = StrapiConfig(base_url="http://localhost:1337", api_token="your-token")
666
+
667
+ with SyncClient(config) as client:
668
+ # List all content types (excludes plugins by default)
669
+ content_types = client.get_content_types()
670
+ for ct in content_types:
671
+ print(f"{ct.uid}: {ct.info.display_name}")
672
+ # api::article.article: Article
673
+ # api::category.category: Category
674
+
675
+ # Include plugin content types
676
+ all_types = client.get_content_types(include_plugins=True)
677
+
678
+ # List all components
679
+ components = client.get_components()
680
+ for comp in components:
681
+ print(f"{comp.category}/{comp.uid}: {comp.info.display_name}")
682
+ # shared/shared.seo: SEO
683
+ # blocks/blocks.hero: Hero Section
684
+
685
+ # Get full schema for a content type
686
+ schema = client.get_content_type_schema("api::article.article")
687
+ print(f"Display name: {schema.display_name}")
688
+ print(f"Plural name: {schema.plural_name}")
689
+
690
+ # Check field types
691
+ print(schema.get_field_type("title")) # "string"
692
+ print(schema.is_relation_field("author")) # True
693
+ print(schema.get_relation_target("author")) # "api::author.author"
694
+
695
+ # Check for components
696
+ print(schema.is_component_field("seo")) # True
697
+ print(schema.get_component_uid("seo")) # "shared.seo"
698
+ ```
699
+
700
+ **Async version:**
701
+
702
+ ```python
703
+ async with AsyncClient(config) as client:
704
+ content_types = await client.get_content_types()
705
+ components = await client.get_components()
706
+ schema = await client.get_content_type_schema("api::article.article")
707
+ ```
708
+
709
+ ### UID Utilities
710
+
711
+ Utility functions for working with Strapi content type UIDs:
712
+
713
+ ```python
714
+ from strapi_kit.utils import (
715
+ uid_to_endpoint,
716
+ uid_to_api_id, # Alias for uid_to_endpoint
717
+ api_id_to_singular,
718
+ uid_to_admin_url,
719
+ extract_model_name,
720
+ is_api_content_type,
721
+ )
722
+
723
+ # Convert UID to API endpoint (pluralized)
724
+ uid_to_endpoint("api::article.article") # "articles"
725
+ uid_to_endpoint("api::category.category") # "categories"
726
+ uid_to_endpoint("api::class.class") # "classes"
727
+
728
+ # Convert plural API ID to singular
729
+ api_id_to_singular("articles") # "article"
730
+ api_id_to_singular("categories") # "category"
731
+ api_id_to_singular("quizzes") # "quiz" (handles -zzes endings)
732
+ api_id_to_singular("people") # "person" (handles irregular plurals)
733
+ api_id_to_singular("children") # "child"
734
+
735
+ # Build admin panel URL
736
+ uid_to_admin_url("api::article.article", "http://localhost:1337")
737
+ # "http://localhost:1337/admin/content-manager/collection-types/api::article.article"
738
+
739
+ uid_to_admin_url("api::homepage.homepage", "http://localhost:1337", kind="singleType")
740
+ # "http://localhost:1337/admin/content-manager/single-types/api::homepage.homepage"
741
+
742
+ # Extract model name from UID
743
+ extract_model_name("api::article.article") # "article"
744
+ extract_model_name("plugin::users-permissions.user") # "user"
745
+
746
+ # Check if UID is an API content type
747
+ is_api_content_type("api::article.article") # True
748
+ is_api_content_type("plugin::users-permissions.user") # False
749
+ ```
750
+
751
+ ### SEO Configuration Detection
752
+
753
+ Detect SEO configuration patterns in content type schemas:
754
+
755
+ ```python
756
+ from strapi_kit.utils import detect_seo_configuration, SEOConfiguration
757
+
758
+ # Detect SEO in a schema dict
759
+ schema = {
760
+ "uid": "api::article.article",
761
+ "attributes": {
762
+ "title": {"type": "string"},
763
+ "seo": {"type": "component", "component": "shared.seo"},
764
+ }
765
+ }
766
+
767
+ config = detect_seo_configuration(schema)
768
+ print(config.has_seo) # True
769
+ print(config.seo_type) # "component"
770
+ print(config.seo_field_name) # "seo"
771
+ print(config.seo_component_uid) # "shared.seo"
772
+ print(config.fields) # {"title": "seo.metaTitle", "description": "seo.metaDescription", ...}
773
+
774
+ # Also detects flat SEO fields
775
+ schema_flat = {
776
+ "uid": "api::page.page",
777
+ "attributes": {
778
+ "metaTitle": {"type": "string"},
779
+ "metaDescription": {"type": "text"},
780
+ "ogImage": {"type": "media"},
781
+ }
782
+ }
783
+
784
+ config = detect_seo_configuration(schema_flat)
785
+ print(config.has_seo) # True
786
+ print(config.seo_type) # "flat"
787
+ print(config.fields) # {"title": "metaTitle", "description": "metaDescription", "og_image": "ogImage"}
788
+ ```
789
+
790
+ **Supported SEO patterns:**
791
+
792
+ - **Component-based**: Fields named `seo`, `meta`, `metadata` with type `component`
793
+ - **Component UIDs**: Components with `seo` in the UID (e.g., `shared.seo`, `custom.page-seo`)
794
+ - **Flat fields**: `metaTitle`, `meta_title`, `seoTitle`, `metaDescription`, `ogTitle`, `canonicalUrl`, `noIndex`, etc.
795
+
657
796
  ### Export/Import with Relation Resolution
658
797
 
659
798
  strapi-kit provides comprehensive export/import functionality with automatic relation resolution for migrating content between Strapi instances.
@@ -732,23 +871,35 @@ We provide two complete migration examples for different use cases:
732
871
  Perfect for straightforward migrations with known content types:
733
872
 
734
873
  ```bash
735
- # 1. Edit examples/simple_migration.py with your configuration
736
- # 2. Run the migration
874
+ # Set environment variables (or edit the script)
875
+ export SOURCE_STRAPI_TOKEN='your-source-token'
876
+ export TARGET_STRAPI_TOKEN='your-target-token'
877
+
878
+ # Run the migration
737
879
  python examples/simple_migration.py
738
880
  ```
739
881
 
740
882
  Features:
741
883
  - ✅ Single-file, easy to understand
742
- - ✅ Migrates specific content types
743
- - ✅ Includes media files
884
+ - ✅ Environment variable support for credentials
885
+ - ✅ Configuration validation before migration
886
+ - ✅ Connection verification for both instances
887
+ - ✅ Timestamped backup files to prevent overwrites
888
+ - ✅ Comprehensive error handling
744
889
  - ✅ Automatic relation resolution
745
- - ✅ Saves backup to JSON
890
+ - ✅ Includes media files
746
891
 
747
892
  #### Full Migration (Production-Ready)
748
893
 
749
894
  Comprehensive migration tool with auto-discovery and verification:
750
895
 
751
896
  ```bash
897
+ # Set environment variables (required)
898
+ export SOURCE_STRAPI_URL="http://localhost:1337"
899
+ export SOURCE_STRAPI_TOKEN="your-source-api-token"
900
+ export TARGET_STRAPI_URL="http://localhost:1338"
901
+ export TARGET_STRAPI_TOKEN="your-target-api-token"
902
+
752
903
  # Export all content from source
753
904
  python examples/full_migration_v5.py export
754
905
 
@@ -763,6 +914,7 @@ python examples/full_migration_v5.py verify
763
914
  ```
764
915
 
765
916
  Features:
917
+ - ✅ **Environment variable configuration** (no hardcoded credentials)
766
918
  - ✅ **Auto-discovers all content types** (no manual configuration needed)
767
919
  - ✅ Progress bars for long operations
768
920
  - ✅ Detailed migration reports
@@ -946,6 +1098,42 @@ db_config = DatabaseConfig(db_connection)
946
1098
  client = SyncClient(db_config)
947
1099
  ```
948
1100
 
1101
+ ## Error Handling
1102
+
1103
+ strapi-kit provides a rich exception hierarchy for precise error handling:
1104
+
1105
+ ```python
1106
+ from strapi_kit import (
1107
+ StrapiError, # Base for all errors
1108
+ ConfigurationError, # Invalid config (missing token, bad URL)
1109
+ ValidationError, # Invalid input/query params
1110
+ AuthenticationError, # HTTP 401
1111
+ AuthorizationError, # HTTP 403
1112
+ NotFoundError, # HTTP 404
1113
+ ConflictError, # HTTP 409
1114
+ ServerError, # HTTP 5xx
1115
+ NetworkError, # Connection issues (base)
1116
+ RateLimitError, # HTTP 429
1117
+ ImportExportError, # Data operations (base)
1118
+ FormatError, # Invalid data format
1119
+ MediaError, # Media upload/download errors
1120
+ )
1121
+
1122
+ try:
1123
+ with SyncClient(config) as client:
1124
+ response = client.get_many("articles")
1125
+ except ConfigurationError as e:
1126
+ print(f"Config issue: {e}")
1127
+ except ValidationError as e:
1128
+ print(f"Invalid query: {e}")
1129
+ except NotFoundError as e:
1130
+ print(f"Not found: {e}")
1131
+ except StrapiError as e:
1132
+ print(f"Strapi error: {e}")
1133
+ ```
1134
+
1135
+ All exceptions inherit from `StrapiError`, making it easy to catch all package-specific errors while still allowing precise handling of specific error types.
1136
+
949
1137
  ## Development
950
1138
 
951
1139
  ### Setup
@@ -1045,7 +1233,7 @@ This project is in active development. Currently implemented:
1045
1233
  - **Query Builder**: `StrapiQuery` fluent API with full type safety
1046
1234
  - **Typed Client Methods**: `get_one()`, `get_many()`, `create()`, `update()`, `remove()`
1047
1235
  - **Dependency Injection**: Full DI support with protocols for testability
1048
- - **93% test coverage** with 196 passing tests
1236
+ - **Full test coverage** with type-safe query building
1049
1237
 
1050
1238
  ### ✅ Phase 3: Media Operations (Complete)
1051
1239
  - **Media Upload**: Single and batch file uploads with metadata
@@ -1061,13 +1249,19 @@ This project is in active development. Currently implemented:
1061
1249
  - **Media Export**: Download and package media files
1062
1250
  - **Content Import**: Import with ID mapping and relation resolution
1063
1251
  - **Schema Caching**: Efficient content type metadata handling
1064
- - **89% overall test coverage** with 355 passing tests
1252
+ - **85% overall test coverage** with 460 passing tests
1253
+
1254
+ ### ✅ Phase 5: Schema Introspection (Complete)
1255
+ - **Content-Type Builder API**: List content types, components, and full schemas
1256
+ - **UID Utilities**: Convert UIDs to endpoints, singularize, build admin URLs
1257
+ - **SEO Detection**: Detect SEO configuration patterns in schemas
1258
+ - **86% overall test coverage** with 528 passing tests
1065
1259
 
1066
- ### 🚧 Phase 5-6: Advanced Features (Planned)
1260
+ ### 🚧 Phase 6: Advanced Features (Planned)
1067
1261
  - Bulk operations with streaming
1068
- - Content type introspection
1069
1262
  - Advanced retry strategies
1070
1263
  - Rate limiting
1264
+ - GraphQL support
1071
1265
 
1072
1266
  ### Key Features
1073
1267
  - **Type-Safe**: Full Pydantic validation and mypy strict mode compliance
@@ -1,28 +1,29 @@
1
- strapi_kit/__init__.py,sha256=GUV-N5HRlNntClmSVgCUli-vNhmsWb8VyS6huk_TV3Y,2177
1
+ strapi_kit/__init__.py,sha256=z4BR2eysdjTvsFaTqyUX0aPnSODMC2MyhdpvtCgWHVY,2177
2
2
  strapi_kit/__version__.py,sha256=oLc_AUMPwiL7J2vgrvXdzVqbSQl2hqkPZ6dNfUx1lTU,478
3
- strapi_kit/_version.py,sha256=huLsL1iGeXWQKZ8bjwDdIWC7JOkj3wnzBh-HFMZl1PY,704
4
- strapi_kit/config_provider.py,sha256=T0KQcNLD_2CvC78Efeq9TBwbxN1WnKdWMekrg7fKQe0,12251
3
+ strapi_kit/_version.py,sha256=QlXZ5JTjE_pgpDaeHk0GTExkc75xUZFmd0hA7kGYCJ0,704
4
+ strapi_kit/config_provider.py,sha256=Eky8mH6XgvgrwzsQuAc4gPpbPby_miycxqQH175rlU4,11864
5
5
  strapi_kit/protocols.py,sha256=wMeGSFCSxeamv2YDzWWWSVJtiGrm__1Xg00QighEbQ4,10971
6
6
  strapi_kit/auth/__init__.py,sha256=VhjbOiyBVSafz3lf2a43bnbSm0J8PG-lguIKHlRplx8,117
7
7
  strapi_kit/auth/api_token.py,sha256=FntOxnf18ZdF0YwGjt0J6DM9tlxmIGZGIplqkLvstl0,1419
8
8
  strapi_kit/cache/__init__.py,sha256=MpqVNsjbE6_QGEwyxZ80h-PFkB8NzDv7xGxJK1g5agQ,126
9
9
  strapi_kit/cache/schema_cache.py,sha256=cmZBS2E0m0YyxpqS7_Z9evDqu_JZxQH086Vv7th7140,6552
10
10
  strapi_kit/client/__init__.py,sha256=R9Ux5bCret4mnXItnFh5MxYlMOjoS4bepPX1KpNSs5w,216
11
- strapi_kit/client/async_client.py,sha256=bj9tMLrTePoMKEECkII1DJ3IoaZ7X4AiB8EwPgBE_IM,35810
12
- strapi_kit/client/base.py,sha256=2ChQyzy-tZbhRn-fuNirsLn8bOErcIquQP1KX800Sm8,16719
13
- strapi_kit/client/sync_client.py,sha256=BeykD1MAFpQHZI0WUGhS8cSi8QNOpgOJiQ1568AL0kA,32927
14
- strapi_kit/exceptions/__init__.py,sha256=zzBuUzGBMhPHcxUMMz8GowRgSALzgP5jsgoUD9-KDHY,698
15
- strapi_kit/exceptions/errors.py,sha256=9Z_mB2412TZoDXZO8VyaB9PnZEeSXgXOzsAnNqWRI3E,5002
11
+ strapi_kit/client/async_client.py,sha256=GUWFfUABcm6tJgWb9CaoYGhfEu7lmZx_nKUr0v97tJ4,39021
12
+ strapi_kit/client/base.py,sha256=wzjDSH1bZ8us7iIuSJbi6C7cyqIKbiOaIBunMAiiIa0,19923
13
+ strapi_kit/client/sync_client.py,sha256=bJGzhdTedIl2nnZqjzASEyejiOHM8-_AlubItp_IqcY,36078
14
+ strapi_kit/exceptions/__init__.py,sha256=lGjEMAbbKO4MXIodY6jxF5x0WerbSZEnYL_r990tzXM,748
15
+ strapi_kit/exceptions/errors.py,sha256=Yc051k-3tCmT7ybJjQXs9V_i6bh0pY4xW6zmTT7i4PQ,5328
16
16
  strapi_kit/export/__init__.py,sha256=s1_1e75FodxpzaC8oWmrXNBUKIXt_0wuhQk5Iz2YUpY,340
17
- strapi_kit/export/exporter.py,sha256=1DDMt4DcG1RaGBiPqvynFIECcZHf5r_A1lh0Llg_IzE,13945
17
+ strapi_kit/export/exporter.py,sha256=F3ow3NlyutdC-yc-cGZwyAoIVCu-8UnbQyOSrBR4QV0,14056
18
18
  strapi_kit/export/importer.py,sha256=8ReQK7UivJGJU78W8RfPCwLSEGcYURzsNlVuI2fvugE,23010
19
19
  strapi_kit/export/media_handler.py,sha256=xmx06M4ehtpNpVDwwuppwGpLwRd9s2M-NNnQ7I1T5Pk,11014
20
20
  strapi_kit/export/relation_resolver.py,sha256=bXsrY80JWdvzmfFZc0UIpluReg9BWWBdr5SXhEqlaCs,5660
21
- strapi_kit/models/__init__.py,sha256=j1wg_hUY4YFycZR3jzYhOQ5wt2ajnSLzIJ_bWTvBAXQ,3104
21
+ strapi_kit/models/__init__.py,sha256=zm-V86_4yWVS0LGezajQvK0lALmHiZtX8o0tC0QVBk0,3441
22
22
  strapi_kit/models/bulk.py,sha256=g1swXgk8nWE_C-u6LIwKJzk2E5xmqMxDMQgY6SzxY7Q,2100
23
23
  strapi_kit/models/config.py,sha256=Nq1pWlDc50wSV3RvQseKG688zlHw8vlNFRZqAPtvj0Q,4543
24
+ strapi_kit/models/content_type.py,sha256=AIONiPq6-ZyNdoAygiR1_ynh-s2d5ti2GvtmnaktzMs,4150
24
25
  strapi_kit/models/enums.py,sha256=sxxlBNwOyxasqI7hwTanrv1kppseIkNUf-3SJF15TH8,2939
25
- strapi_kit/models/export_format.py,sha256=Ii-mow_ekt_1O-oLKa5VEdsJdO--RvouOSSrWi3H4IA,5301
26
+ strapi_kit/models/export_format.py,sha256=x8cH-uktCaUVxOJCVtLdS1gs3NpNqTqExWQa5wWoEqc,5351
26
27
  strapi_kit/models/import_options.py,sha256=aRjWSI2ZOPl8j0ZiLlR8TfAjLrpzn7HBpK1LQ3Rt1IA,4795
27
28
  strapi_kit/models/schema.py,sha256=qNU7v_HF0AESDqmmKmMy_ERPOI-zUqFCujlAjTZ1Lo8,2489
28
29
  strapi_kit/models/request/__init__.py,sha256=RvuVgPvc2tAx9A_Esh04SZZ5Oi1GFiYpxdg90TLsd6A,54
@@ -30,7 +31,7 @@ strapi_kit/models/request/fields.py,sha256=VrPyf0Pg_EQ3z2IyzBhaw_4fr7N5VWJRcN2Li
30
31
  strapi_kit/models/request/filters.py,sha256=3qMzI8cTMfYCFWRAGMbw6DmEBtD2yUWB4UswABQavR4,19274
31
32
  strapi_kit/models/request/pagination.py,sha256=hXFp534JutocVgWN0L0kInwSVGmhzhCJGTPdNzpJpUc,5244
32
33
  strapi_kit/models/request/populate.py,sha256=xYjOFdauqxHtIEaYI5w-hXeX92TcfIdYGybJzrSdxYA,9399
33
- strapi_kit/models/request/query.py,sha256=46lLU7fajwHbqtnawedqZ4zXekX74y-MdhriGd8sz0c,14855
34
+ strapi_kit/models/request/query.py,sha256=3s9TQlskxCb6ShCj9Lyu6Se4whRpuaxsriZukPAdPDQ,15074
34
35
  strapi_kit/models/request/sort.py,sha256=BJqBt5ZEw3LkyHWfKHmQ7NtOtZMWFP3tNxdgbrsSJhw,4654
35
36
  strapi_kit/models/response/__init__.py,sha256=1Cn009-Zp-vLcRSV-E65TaszK1b09qCVi6_LNKHBMNo,56
36
37
  strapi_kit/models/response/base.py,sha256=mutKKPSUMdd4Jsg7bv18bad9OwNUdKHjutHDloz9_5E,1982
@@ -42,14 +43,15 @@ strapi_kit/models/response/relation.py,sha256=wZb4HIwM6RChZmFDbtKgLjunGS1dauxwm8
42
43
  strapi_kit/models/response/v4.py,sha256=7i-HmNIkL6alyM0o7Y-u3v57O8ROMYH4w0HH95_p9iw,1996
43
44
  strapi_kit/models/response/v5.py,sha256=bXHK4TH15aUy3ssxZZBz2myI6JR4BYnrSRWitju1HoQ,1838
44
45
  strapi_kit/operations/__init__.py,sha256=9tUk9gZQQThF93jXjB38XM20rPCfp6QVhgmiYTC28AY,355
45
- strapi_kit/operations/media.py,sha256=v6RBuy4TWqVz7yMgIiOls38fEs7HjClCWL-Z2O5Ntr8,7144
46
- strapi_kit/operations/streaming.py,sha256=RVwzB4LSlUtHdmTyltKEUriW41PVEc6AfCJh-WfWS1k,4735
46
+ strapi_kit/operations/media.py,sha256=26eUo-o6UDtHOKNuVc8bvoXht037-bH114glLvk-RQg,7498
47
+ strapi_kit/operations/streaming.py,sha256=A6Czlq_c2yIc7vQMx4OwLURBgdTPnnOfa80z-Mw5pMQ,4796
47
48
  strapi_kit/parsers/__init__.py,sha256=-4WSHKbFhnbOB4j7MF2qyktgkb6t8RY3slTYKV4vhvg,142
48
49
  strapi_kit/parsers/version_detecting.py,sha256=i6Wh7NSQYPWSv0GR63ZJLuPF6BqFwQ_Y7J3q7l7h1JQ,6421
49
- strapi_kit/utils/__init__.py,sha256=kQdkXpAw3IgAG4fcKF7FswYag8o7MUWnwM-AA578_4g,368
50
- strapi_kit/utils/rate_limiter.py,sha256=sm-p7aAqsri0sHsj3bYbv9ib022goBXGtMgTsFEIlUs,6306
51
- strapi_kit/utils/uid.py,sha256=DRRa9MNkcQDI2RNEkwAjWK9HMx8Sg4Waxi8uA2fdPAg,2636
52
- strapi_kit-0.0.2.dist-info/METADATA,sha256=XgFc69X1JvE_MJ8TppUDXbz1yGTkmk9xMU5EQTiJFvU,31236
53
- strapi_kit-0.0.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
54
- strapi_kit-0.0.2.dist-info/licenses/LICENSE,sha256=lN0YUtXlAFBt9MNYr2F0GJEYdprxDOTIqcVhKxMsaTI,1067
55
- strapi_kit-0.0.2.dist-info/RECORD,,
50
+ strapi_kit/utils/__init__.py,sha256=FFSuu9W6Yt1r0OEU55bs9zLz2RuAy0wCVPfzN2BRz7E,823
51
+ strapi_kit/utils/rate_limiter.py,sha256=c-oAgCILG-6nrjhxIXEx3sKqRgkxOHcNJE496ix7aVA,6367
52
+ strapi_kit/utils/seo.py,sha256=p1CR3NGPJfarLosqRa3PAgigS9l9IB_LXUMjaZBXDeM,9317
53
+ strapi_kit/utils/uid.py,sha256=IcGlFKxtyIIWm9TKVMDX4WseSCMS5FLLDNJItSZgIoA,6797
54
+ strapi_kit-0.0.4.dist-info/METADATA,sha256=p7pz_bu7WnJR-3g9HenyV7hnYh-N1sGsJ_zAYKcp5TI,38069
55
+ strapi_kit-0.0.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
56
+ strapi_kit-0.0.4.dist-info/licenses/LICENSE,sha256=lN0YUtXlAFBt9MNYr2F0GJEYdprxDOTIqcVhKxMsaTI,1067
57
+ strapi_kit-0.0.4.dist-info/RECORD,,