myairtable 0.1.0__tar.gz
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.
- myairtable-0.1.0/.beads/README.md +85 -0
- myairtable-0.1.0/.gitignore +25 -0
- myairtable-0.1.0/LICENSE +21 -0
- myairtable-0.1.0/PKG-INFO +468 -0
- myairtable-0.1.0/README.md +437 -0
- myairtable-0.1.0/pyproject.toml +112 -0
- myairtable-0.1.0/src/myairtable/__init__.py +1 -0
- myairtable-0.1.0/src/myairtable/formulas/__init__.py +0 -0
- myairtable-0.1.0/src/myairtable/formulas/formula_condenser.py +42 -0
- myairtable-0.1.0/src/myairtable/formulas/formula_flattener.py +184 -0
- myairtable-0.1.0/src/myairtable/formulas/formula_formatter.py +331 -0
- myairtable-0.1.0/src/myairtable/formulas/formula_highlighter.py +82 -0
- myairtable-0.1.0/src/myairtable/formulas/formula_sanitizer.py +57 -0
- myairtable-0.1.0/src/myairtable/formulas/formula_tokenizer.py +405 -0
- myairtable-0.1.0/src/myairtable/formulas/formula_transpiler.py +1695 -0
- myairtable-0.1.0/src/myairtable/generators/__init__.py +0 -0
- myairtable-0.1.0/src/myairtable/generators/cpp.py +673 -0
- myairtable-0.1.0/src/myairtable/generators/csharp.py +614 -0
- myairtable-0.1.0/src/myairtable/generators/csv.py +76 -0
- myairtable-0.1.0/src/myairtable/generators/go.py +433 -0
- myairtable-0.1.0/src/myairtable/generators/html.py +721 -0
- myairtable-0.1.0/src/myairtable/generators/java.py +962 -0
- myairtable-0.1.0/src/myairtable/generators/javascript.py +826 -0
- myairtable-0.1.0/src/myairtable/generators/kotlin.py +721 -0
- myairtable-0.1.0/src/myairtable/generators/markdown.py +322 -0
- myairtable-0.1.0/src/myairtable/generators/mermaid.py +197 -0
- myairtable-0.1.0/src/myairtable/generators/python.py +1043 -0
- myairtable-0.1.0/src/myairtable/generators/rust.py +1036 -0
- myairtable-0.1.0/src/myairtable/generators/swift.py +967 -0
- myairtable-0.1.0/src/myairtable/generators/typescript.py +937 -0
- myairtable-0.1.0/src/myairtable/main.py +562 -0
- myairtable-0.1.0/src/myairtable/meta.py +1255 -0
- myairtable-0.1.0/src/myairtable/meta_types.py +371 -0
- myairtable-0.1.0/src/myairtable/py.typed +0 -0
- myairtable-0.1.0/src/myairtable/result_store.py +245 -0
- myairtable-0.1.0/src/myairtable/schema_tools.py +1474 -0
- myairtable-0.1.0/src/myairtable/schema_tools_cli.py +342 -0
- myairtable-0.1.0/src/myairtable/static/__init__.py +0 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_attachment.hpp +102 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_button.hpp +36 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_client.hpp +308 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_collaborator.hpp +43 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_date.hpp +216 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_exception.hpp +129 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_json.hpp +53 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_model.hpp +136 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_query.hpp +81 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_record.hpp +42 -0
- myairtable-0.1.0/src/myairtable/static/cpp/airtable_tz.hpp +26 -0
- myairtable-0.1.0/src/myairtable/static/cpp/cache_store.hpp +133 -0
- myairtable-0.1.0/src/myairtable/static/cpp/curl_transport.hpp +175 -0
- myairtable-0.1.0/src/myairtable/static/cpp/dict_table.hpp +185 -0
- myairtable-0.1.0/src/myairtable/static/cpp/error_value.hpp +27 -0
- myairtable-0.1.0/src/myairtable/static/cpp/fields.hpp +166 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_attachments_field.hpp +19 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_boolean_field.hpp +19 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_date_field.hpp +127 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_field.hpp +27 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_id.hpp +33 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_lookup_field.hpp +19 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_multi_select_field.hpp +13 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_number_field.hpp +32 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_single_select_field.hpp +13 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_text_field.hpp +13 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formula_text_ops.hpp +119 -0
- myairtable-0.1.0/src/myairtable/static/cpp/formulas.hpp +112 -0
- myairtable-0.1.0/src/myairtable/static/cpp/maybe_special_or_error.hpp +97 -0
- myairtable-0.1.0/src/myairtable/static/cpp/my_airtable_runtime_info.hpp +13 -0
- myairtable-0.1.0/src/myairtable/static/cpp/orm_table.hpp +331 -0
- myairtable-0.1.0/src/myairtable/static/cpp/runtime.hpp +217 -0
- myairtable-0.1.0/src/myairtable/static/cpp/runtime_array.hpp +103 -0
- myairtable-0.1.0/src/myairtable/static/cpp/runtime_date.hpp +433 -0
- myairtable-0.1.0/src/myairtable/static/cpp/runtime_logic.hpp +79 -0
- myairtable-0.1.0/src/myairtable/static/cpp/runtime_math.hpp +204 -0
- myairtable-0.1.0/src/myairtable/static/cpp/runtime_regex.hpp +49 -0
- myairtable-0.1.0/src/myairtable/static/cpp/runtime_string.hpp +346 -0
- myairtable-0.1.0/src/myairtable/static/cpp/sort.hpp +27 -0
- myairtable-0.1.0/src/myairtable/static/cpp/special_number.hpp +30 -0
- myairtable-0.1.0/src/myairtable/static/cpp/vec_or_value.hpp +120 -0
- myairtable-0.1.0/src/myairtable/static/cpp/vendor/date/date.h +8356 -0
- myairtable-0.1.0/src/myairtable/static/cpp/vendor/date/ios.h +50 -0
- myairtable-0.1.0/src/myairtable/static/cpp/vendor/date/tz.cpp +4375 -0
- myairtable-0.1.0/src/myairtable/static/cpp/vendor/date/tz.h +2808 -0
- myairtable-0.1.0/src/myairtable/static/cpp/vendor/date/tz_private.h +315 -0
- myairtable-0.1.0/src/myairtable/static/cpp/vendor/nlohmann/json.hpp +25526 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableAttachment.cs +23 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableButton.cs +4 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableClient.cs +399 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableCollaborator.cs +10 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableDateConverter.cs +46 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableDurationConverter.cs +21 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableException.cs +94 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableJson.cs +35 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableModel.cs +147 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableQuery.cs +98 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableRecord.cs +6 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableRuntime.cs +201 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableRuntimeArray.cs +102 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableRuntimeDate.cs +287 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableRuntimeLogic.cs +47 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableRuntimeMath.cs +177 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableRuntimeRegex.cs +47 -0
- myairtable-0.1.0/src/myairtable/static/csharp/AirtableRuntimeString.cs +187 -0
- myairtable-0.1.0/src/myairtable/static/csharp/CacheStore.cs +183 -0
- myairtable-0.1.0/src/myairtable/static/csharp/DictTable.cs +255 -0
- myairtable-0.1.0/src/myairtable/static/csharp/ErrorValue.cs +4 -0
- myairtable-0.1.0/src/myairtable/static/csharp/Fields.cs +116 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaAttachmentsField.cs +17 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaBooleanField.cs +17 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaDateField.cs +132 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaField.cs +18 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaId.cs +20 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaLookupField.cs +17 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaMultiSelectField.cs +8 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaNumberField.cs +32 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaSingleSelectField.cs +8 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaTextField.cs +8 -0
- myairtable-0.1.0/src/myairtable/static/csharp/FormulaTextOps.cs +115 -0
- myairtable-0.1.0/src/myairtable/static/csharp/Formulas.cs +75 -0
- myairtable-0.1.0/src/myairtable/static/csharp/IAirtableView.cs +7 -0
- myairtable-0.1.0/src/myairtable/static/csharp/MaybeSpecialOrError.cs +24 -0
- myairtable-0.1.0/src/myairtable/static/csharp/MaybeSpecialOrErrorConverter.cs +69 -0
- myairtable-0.1.0/src/myairtable/static/csharp/ModelOps.cs +52 -0
- myairtable-0.1.0/src/myairtable/static/csharp/OrmTable.cs +456 -0
- myairtable-0.1.0/src/myairtable/static/csharp/Sort.cs +18 -0
- myairtable-0.1.0/src/myairtable/static/csharp/SpecialNumber.cs +4 -0
- myairtable-0.1.0/src/myairtable/static/csharp/VecOrValue.cs +47 -0
- myairtable-0.1.0/src/myairtable/static/csharp/VecOrValueConverter.cs +61 -0
- myairtable-0.1.0/src/myairtable/static/go/airtable_runtime_test.go +374 -0
- myairtable-0.1.0/src/myairtable/static/go/cache.go +80 -0
- myairtable-0.1.0/src/myairtable/static/go/cache_store_test.go +126 -0
- myairtable-0.1.0/src/myairtable/static/go/client.go +426 -0
- myairtable-0.1.0/src/myairtable/static/go/client_cache_policy_test.go +63 -0
- myairtable-0.1.0/src/myairtable/static/go/client_retry_hermetic_test.go +203 -0
- myairtable-0.1.0/src/myairtable/static/go/client_url_encoding_test.go +94 -0
- myairtable-0.1.0/src/myairtable/static/go/date_decoding_test.go +148 -0
- myairtable-0.1.0/src/myairtable/static/go/dict_table.go +130 -0
- myairtable-0.1.0/src/myairtable/static/go/dx_helpers_test.go +167 -0
- myairtable-0.1.0/src/myairtable/static/go/errors.go +101 -0
- myairtable-0.1.0/src/myairtable/static/go/exception_decoding_test.go +122 -0
- myairtable-0.1.0/src/myairtable/static/go/fields.go +66 -0
- myairtable-0.1.0/src/myairtable/static/go/fields_dual_access_test.go +139 -0
- myairtable-0.1.0/src/myairtable/static/go/formula.go +106 -0
- myairtable-0.1.0/src/myairtable/static/go/formula_date.go +185 -0
- myairtable-0.1.0/src/myairtable/static/go/formula_fields.go +344 -0
- myairtable-0.1.0/src/myairtable/static/go/formula_test.go +539 -0
- myairtable-0.1.0/src/myairtable/static/go/go.mod +3 -0
- myairtable-0.1.0/src/myairtable/static/go/helpers.go +29 -0
- myairtable-0.1.0/src/myairtable/static/go/json.go +162 -0
- myairtable-0.1.0/src/myairtable/static/go/maybe_special_or_error.go +84 -0
- myairtable-0.1.0/src/myairtable/static/go/model.go +160 -0
- myairtable-0.1.0/src/myairtable/static/go/prototype_test.go +262 -0
- myairtable-0.1.0/src/myairtable/static/go/query.go +94 -0
- myairtable-0.1.0/src/myairtable/static/go/query_build_test.go +164 -0
- myairtable-0.1.0/src/myairtable/static/go/review_fixes_test.go +167 -0
- myairtable-0.1.0/src/myairtable/static/go/runtime.go +197 -0
- myairtable-0.1.0/src/myairtable/static/go/runtime_functions.go +1217 -0
- myairtable-0.1.0/src/myairtable/static/go/runtime_info.go +4 -0
- myairtable-0.1.0/src/myairtable/static/go/special_error_decoding_test.go +163 -0
- myairtable-0.1.0/src/myairtable/static/go/table.go +182 -0
- myairtable-0.1.0/src/myairtable/static/go/table_bounded_ops_test.go +180 -0
- myairtable-0.1.0/src/myairtable/static/go/types.go +70 -0
- myairtable-0.1.0/src/myairtable/static/go/value_coercion_test.go +125 -0
- myairtable-0.1.0/src/myairtable/static/go/vec_or_value.go +59 -0
- myairtable-0.1.0/src/myairtable/static/go/write_option.go +30 -0
- myairtable-0.1.0/src/myairtable/static/go/write_option_test.go +151 -0
- myairtable-0.1.0/src/myairtable/static/html/script.js +256 -0
- myairtable-0.1.0/src/myairtable/static/html/style.css +730 -0
- myairtable-0.1.0/src/myairtable/static/html/template-footer.html +4 -0
- myairtable-0.1.0/src/myairtable/static/html/template-header.html +36 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableAttachment.java +76 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableButton.java +8 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableClient.java +478 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableCollaborator.java +57 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableDateParser.java +54 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableErrorEnvelope.java +29 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableException.java +201 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableJacksonModule.java +81 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableJson.java +45 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableModel.java +102 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableQuery.java +336 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableRecord.java +13 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableRuntime.java +1209 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableThumbnails.java +12 -0
- myairtable-0.1.0/src/myairtable/static/java/AirtableView.java +15 -0
- myairtable-0.1.0/src/myairtable/static/java/CacheStore.java +188 -0
- myairtable-0.1.0/src/myairtable/static/java/DictTable.java +303 -0
- myairtable-0.1.0/src/myairtable/static/java/ErrorValue.java +13 -0
- myairtable-0.1.0/src/myairtable/static/java/Fields.java +215 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaAttachmentsField.java +37 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaBooleanField.java +35 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaDateComparison.java +67 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaDateField.java +139 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaDateLiteral.java +20 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaDateOperand.java +15 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaField.java +28 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaId.java +25 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaLookupField.java +35 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaMultiSelectField.java +20 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaNumberField.java +62 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaSingleSelectField.java +20 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaTextField.java +20 -0
- myairtable-0.1.0/src/myairtable/static/java/FormulaTextOps.java +174 -0
- myairtable-0.1.0/src/myairtable/static/java/Formulas.java +99 -0
- myairtable-0.1.0/src/myairtable/static/java/MaybeSpecialOrError.java +51 -0
- myairtable-0.1.0/src/myairtable/static/java/MaybeSpecialOrErrorDeserializer.java +73 -0
- myairtable-0.1.0/src/myairtable/static/java/MaybeSpecialOrErrorSerializer.java +29 -0
- myairtable-0.1.0/src/myairtable/static/java/ModelOps.java +51 -0
- myairtable-0.1.0/src/myairtable/static/java/MyAirtableRuntimeInfo.java +12 -0
- myairtable-0.1.0/src/myairtable/static/java/OrmTable.java +429 -0
- myairtable-0.1.0/src/myairtable/static/java/Sort.java +17 -0
- myairtable-0.1.0/src/myairtable/static/java/SortDirection.java +25 -0
- myairtable-0.1.0/src/myairtable/static/java/SpecialNumber.java +13 -0
- myairtable-0.1.0/src/myairtable/static/java/VecOrValue.java +67 -0
- myairtable-0.1.0/src/myairtable/static/java/VecOrValueDeserializer.java +66 -0
- myairtable-0.1.0/src/myairtable/static/java/VecOrValueSerializer.java +36 -0
- myairtable-0.1.0/src/myairtable/static/javascript/airtable-model.js +431 -0
- myairtable-0.1.0/src/myairtable/static/javascript/airtable-runtime.js +470 -0
- myairtable-0.1.0/src/myairtable/static/javascript/airtable-table.js +628 -0
- myairtable-0.1.0/src/myairtable/static/javascript/errors.js +165 -0
- myairtable-0.1.0/src/myairtable/static/javascript/formula.js +704 -0
- myairtable-0.1.0/src/myairtable/static/javascript/helpers.js +140 -0
- myairtable-0.1.0/src/myairtable/static/javascript/linked-record.js +238 -0
- myairtable-0.1.0/src/myairtable/static/javascript/special-types.js +64 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/AirtableClient.kt +423 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/AirtableException.kt +123 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/AirtableJson.kt +227 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/AirtableModel.kt +123 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/AirtableQuery.kt +70 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/AirtableRuntime.kt +865 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/CacheStore.kt +139 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/DictTable.kt +262 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/Fields.kt +163 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/Formula.kt +542 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/MyAirtableRuntimeInfo.kt +10 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/OrmTable.kt +349 -0
- myairtable-0.1.0/src/myairtable/static/kotlin/Types.kt +400 -0
- myairtable-0.1.0/src/myairtable/static/python/__init__.py +4 -0
- myairtable-0.1.0/src/myairtable/static/python/airtable_runtime.py +476 -0
- myairtable-0.1.0/src/myairtable/static/python/airtable_table.py +109 -0
- myairtable-0.1.0/src/myairtable/static/python/dict_table.py +471 -0
- myairtable-0.1.0/src/myairtable/static/python/formula.py +707 -0
- myairtable-0.1.0/src/myairtable/static/python/helpers.py +97 -0
- myairtable-0.1.0/src/myairtable/static/python/orm_table.py +512 -0
- myairtable-0.1.0/src/myairtable/static/python/schema_types.py +69 -0
- myairtable-0.1.0/src/myairtable/static/python/special_types.py +36 -0
- myairtable-0.1.0/src/myairtable/static/python/table_helpers.py +75 -0
- myairtable-0.1.0/src/myairtable/static/rust/airtable_model.rs +180 -0
- myairtable-0.1.0/src/myairtable/static/rust/airtable_runtime.rs +1177 -0
- myairtable-0.1.0/src/myairtable/static/rust/client.rs +548 -0
- myairtable-0.1.0/src/myairtable/static/rust/error.rs +83 -0
- myairtable-0.1.0/src/myairtable/static/rust/formula.rs +702 -0
- myairtable-0.1.0/src/myairtable/static/rust/lib.rs +17 -0
- myairtable-0.1.0/src/myairtable/static/rust/orm_table.rs +305 -0
- myairtable-0.1.0/src/myairtable/static/rust/pagination.rs +10 -0
- myairtable-0.1.0/src/myairtable/static/rust/struct_table.rs +212 -0
- myairtable-0.1.0/src/myairtable/static/rust/types.rs +474 -0
- myairtable-0.1.0/src/myairtable/static/swift/AirtableClient.swift +375 -0
- myairtable-0.1.0/src/myairtable/static/swift/AirtableError.swift +111 -0
- myairtable-0.1.0/src/myairtable/static/swift/AirtableModel.swift +205 -0
- myairtable-0.1.0/src/myairtable/static/swift/AirtableQuery.swift +155 -0
- myairtable-0.1.0/src/myairtable/static/swift/AirtableRuntime.swift +859 -0
- myairtable-0.1.0/src/myairtable/static/swift/CacheStore.swift +120 -0
- myairtable-0.1.0/src/myairtable/static/swift/DictTable.swift +338 -0
- myairtable-0.1.0/src/myairtable/static/swift/Fields.swift +147 -0
- myairtable-0.1.0/src/myairtable/static/swift/Formula.swift +425 -0
- myairtable-0.1.0/src/myairtable/static/swift/OrmTable.swift +353 -0
- myairtable-0.1.0/src/myairtable/static/swift/Placeholder.swift +8 -0
- myairtable-0.1.0/src/myairtable/static/swift/Types.swift +327 -0
- myairtable-0.1.0/src/myairtable/static/typescript/airtable-model.ts +460 -0
- myairtable-0.1.0/src/myairtable/static/typescript/airtable-runtime.ts +490 -0
- myairtable-0.1.0/src/myairtable/static/typescript/airtable-table.ts +826 -0
- myairtable-0.1.0/src/myairtable/static/typescript/errors.ts +171 -0
- myairtable-0.1.0/src/myairtable/static/typescript/formula.ts +732 -0
- myairtable-0.1.0/src/myairtable/static/typescript/helpers.ts +133 -0
- myairtable-0.1.0/src/myairtable/static/typescript/linked-record.ts +292 -0
- myairtable-0.1.0/src/myairtable/static/typescript/schema-types.ts +66 -0
- myairtable-0.1.0/src/myairtable/static/typescript/special-types.ts +81 -0
- myairtable-0.1.0/src/myairtable/tools_cli.py +45 -0
- myairtable-0.1.0/src/myairtable/utils/__init__.py +0 -0
- myairtable-0.1.0/src/myairtable/utils/helpers.py +353 -0
- myairtable-0.1.0/src/myairtable/utils/mermaid_to_image.py +202 -0
- myairtable-0.1.0/src/myairtable/utils/type_mapper.py +1127 -0
- myairtable-0.1.0/src/myairtable/utils/verbose.py +3 -0
- myairtable-0.1.0/src/myairtable/utils/write_to_cpp_file.py +310 -0
- myairtable-0.1.0/src/myairtable/utils/write_to_csharp_file.py +331 -0
- myairtable-0.1.0/src/myairtable/utils/write_to_file.py +151 -0
- myairtable-0.1.0/src/myairtable/utils/write_to_go_file.py +317 -0
- myairtable-0.1.0/src/myairtable/utils/write_to_java_file.py +314 -0
- myairtable-0.1.0/src/myairtable/utils/write_to_kotlin_file.py +231 -0
- myairtable-0.1.0/src/myairtable/utils/write_to_swift_file.py +290 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Beads - AI-Native Issue Tracking
|
|
2
|
+
|
|
3
|
+
Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.
|
|
4
|
+
|
|
5
|
+
## What is Beads?
|
|
6
|
+
|
|
7
|
+
Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.
|
|
8
|
+
|
|
9
|
+
**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Essential Commands
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Create new issues
|
|
17
|
+
bd create "Add user authentication"
|
|
18
|
+
|
|
19
|
+
# View all issues
|
|
20
|
+
bd list
|
|
21
|
+
|
|
22
|
+
# View issue details
|
|
23
|
+
bd show <issue-id>
|
|
24
|
+
|
|
25
|
+
# Update issue status
|
|
26
|
+
bd update <issue-id> --status in_progress
|
|
27
|
+
bd update <issue-id> --status done
|
|
28
|
+
|
|
29
|
+
# Sync with git remote
|
|
30
|
+
bd sync
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Working with Issues
|
|
34
|
+
|
|
35
|
+
Issues in Beads are:
|
|
36
|
+
|
|
37
|
+
- **Git-native**: Stored in `.beads/issues.jsonl` and synced like code
|
|
38
|
+
- **AI-friendly**: CLI-first design works perfectly with AI coding agents
|
|
39
|
+
- **Branch-aware**: Issues can follow your branch workflow
|
|
40
|
+
- **Always in sync**: Auto-syncs with your commits
|
|
41
|
+
|
|
42
|
+
## Why Beads?
|
|
43
|
+
|
|
44
|
+
✨ **AI-Native Design**
|
|
45
|
+
|
|
46
|
+
- Built specifically for AI-assisted development workflows
|
|
47
|
+
- CLI-first interface works seamlessly with AI coding agents
|
|
48
|
+
- No context switching to web UIs
|
|
49
|
+
|
|
50
|
+
🚀 **Developer Focused**
|
|
51
|
+
|
|
52
|
+
- Issues live in your repo, right next to your code
|
|
53
|
+
- Works offline, syncs when you push
|
|
54
|
+
- Fast, lightweight, and stays out of your way
|
|
55
|
+
|
|
56
|
+
🔧 **Git Integration**
|
|
57
|
+
|
|
58
|
+
- Automatic sync with git commits
|
|
59
|
+
- Branch-aware issue tracking
|
|
60
|
+
- Intelligent JSONL merge resolution
|
|
61
|
+
|
|
62
|
+
## Get Started with Beads
|
|
63
|
+
|
|
64
|
+
Try Beads in your own projects:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Install Beads
|
|
68
|
+
curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
|
|
69
|
+
|
|
70
|
+
# Initialize in your repo
|
|
71
|
+
bd init
|
|
72
|
+
|
|
73
|
+
# Create your first issue
|
|
74
|
+
bd create "Try out Beads"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Learn More
|
|
78
|
+
|
|
79
|
+
- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
|
|
80
|
+
- **Quick Start Guide**: Run `bd quickstart`
|
|
81
|
+
- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
_Beads: Issue tracking that moves at the speed of thought_ ⚡
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
.env
|
|
3
|
+
output/
|
|
4
|
+
dist/
|
|
5
|
+
node_modules/
|
|
6
|
+
.claude/settings.local.json
|
|
7
|
+
.DS_Store
|
|
8
|
+
*egg-info*
|
|
9
|
+
target/
|
|
10
|
+
.data/
|
|
11
|
+
|
|
12
|
+
# Swift
|
|
13
|
+
.build/
|
|
14
|
+
*.xcodeproj/xcuserdata/
|
|
15
|
+
Package.resolved
|
|
16
|
+
|
|
17
|
+
# Gradle (Kotlin projects)
|
|
18
|
+
.gradle/
|
|
19
|
+
**/build/
|
|
20
|
+
.kotlin/
|
|
21
|
+
|
|
22
|
+
# C# / .NET
|
|
23
|
+
bin/
|
|
24
|
+
obj/
|
|
25
|
+
*.user
|
myairtable-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Daniel Baughman
|
|
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.
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: myairtable
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: An Airtable code generator, focused on developer experience.
|
|
5
|
+
Project-URL: Homepage, https://github.com/danielrbaughman/myairtable
|
|
6
|
+
Project-URL: Repository, https://github.com/danielrbaughman/myairtable
|
|
7
|
+
Project-URL: Issues, https://github.com/danielrbaughman/myairtable/issues
|
|
8
|
+
Author: Daniel Baughman
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: airtable,code-generation,codegen,formula,orm,schema
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.12
|
|
19
|
+
Requires-Dist: httpx>=0.28.1
|
|
20
|
+
Requires-Dist: pydantic>=2.11.7
|
|
21
|
+
Requires-Dist: rich>=13.0
|
|
22
|
+
Requires-Dist: typer-verbose>=0.1.2
|
|
23
|
+
Requires-Dist: typing-extensions>=4.12.0
|
|
24
|
+
Provides-Extra: cli
|
|
25
|
+
Requires-Dist: dotenv>=0.9.9; extra == 'cli'
|
|
26
|
+
Requires-Dist: mermaid-cli>=0.1.2; extra == 'cli'
|
|
27
|
+
Requires-Dist: pyairtable>=3.2.0; extra == 'cli'
|
|
28
|
+
Requires-Dist: pyperclip>=1.11.0; extra == 'cli'
|
|
29
|
+
Requires-Dist: typer>=0.16.1; extra == 'cli'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# myAirtable
|
|
33
|
+
|
|
34
|
+
An Airtable code generator, focused on developer experience.
|
|
35
|
+
|
|
36
|
+
> [!WARNING]
|
|
37
|
+
> myAirtable is under active development.
|
|
38
|
+
|
|
39
|
+
Languages supported:
|
|
40
|
+
|
|
41
|
+
- Python (via [pyAirtable](https://pyairtable.readthedocs.io/en/stable/))
|
|
42
|
+
- TypeScript (via [airtable.js](https://github.com/Airtable/airtable.js))
|
|
43
|
+
- JavaScript (via [airtable.js](https://github.com/Airtable/airtable.js))
|
|
44
|
+
- Rust (via a custom-built client)
|
|
45
|
+
- Swift (via a custom-built client)
|
|
46
|
+
- Kotlin (via a custom-built client on [Ktor](https://ktor.io) + [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization))
|
|
47
|
+
- Java (via a custom-built client on the JDK's `java.net.http.HttpClient` + [Jackson](https://github.com/FasterXML/jackson-databind))
|
|
48
|
+
- Go (via a custom-built client on the standard library — `net/http` + `encoding/json`, zero third-party dependencies)
|
|
49
|
+
- C# (via a custom-built .NET 8 client on `HttpClient` + `System.Text.Json`, async/await, zero third-party dependencies)
|
|
50
|
+
- C++ (via a custom-built C++20 client on **libcurl** + a vendored [nlohmann/json](https://github.com/nlohmann/json); header-only distribution)
|
|
51
|
+
|
|
52
|
+
### Kotlin
|
|
53
|
+
|
|
54
|
+
The generated Kotlin code uses `@Serializable` models, so the **kotlinx.serialization compiler plugin is REQUIRED** — without `kotlin("plugin.serialization")` the generated code will not compile. A known-good Gradle setup (`build.gradle.kts`):
|
|
55
|
+
|
|
56
|
+
```kotlin
|
|
57
|
+
plugins {
|
|
58
|
+
kotlin("jvm") version "2.2.20"
|
|
59
|
+
kotlin("plugin.serialization") version "2.2.20" // REQUIRED for the generated @Serializable models
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
sourceSets {
|
|
63
|
+
main {
|
|
64
|
+
kotlin.srcDir("path/to/generated/output") // wherever you generate into
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
dependencies {
|
|
69
|
+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
|
|
70
|
+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
|
|
71
|
+
implementation("io.ktor:ktor-client-core:3.2.3")
|
|
72
|
+
implementation("io.ktor:ktor-client-cio:3.2.3")
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Java
|
|
77
|
+
|
|
78
|
+
The generated Java code targets **Java 21+** (sealed interfaces, records, pattern-matching switch) and is a plain blocking API (cheap on virtual threads). It only needs Jackson databind on the classpath:
|
|
79
|
+
|
|
80
|
+
```kotlin
|
|
81
|
+
java {
|
|
82
|
+
toolchain { languageVersion = JavaLanguageVersion.of(21) }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
sourceSets {
|
|
86
|
+
main {
|
|
87
|
+
java.srcDir("path/to/generated/output") // wherever you generate into
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
dependencies {
|
|
92
|
+
implementation("com.fasterxml.jackson.core:jackson-databind:2.18.2")
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
> [!IMPORTANT]
|
|
97
|
+
> Do NOT register `jackson-datatype-jsr310` (or call `findAndRegisterModules()`) on the runtime's mapper — the bundled `AirtableJacksonModule` owns `Instant`/`Duration` encoding (Airtable durations are numeric seconds, not ISO `PT…` strings).
|
|
98
|
+
|
|
99
|
+
Models are mutable POJOs created through a generated `Builder` (the Java analog of the other targets' named arguments): `PrimaryModel.builder().primaryKey("x").build()`. Bulk deletes are named `deleteAll(ids)` / `deleteModels(models)` because Java's type erasure forbids overloading `delete(List<String>)` against `delete(List<Model>)`.
|
|
100
|
+
|
|
101
|
+
#### Error handling
|
|
102
|
+
|
|
103
|
+
Every failure is an `AirtableException` — a sealed, **unchecked** hierarchy (checked exceptions would poison every generated signature). The subtypes are `Http` (non-2xx, with `statusCode()`/`body()`), `Api` (a structured Airtable error envelope, with `code()`/`apiMessage()`), `RateLimited` (429, with `retryAfterSeconds()`), `Decoding`, `Network`, `InvalidUrl`, and `MissingCredentials`. Catch the base type for everything, or a specific subtype for targeted handling:
|
|
104
|
+
|
|
105
|
+
```java
|
|
106
|
+
try {
|
|
107
|
+
var contacts = airtable.primary().get();
|
|
108
|
+
} catch (AirtableException.RateLimited e) {
|
|
109
|
+
// Only reached after retries are exhausted (see below).
|
|
110
|
+
log.warn("rate limited; retry after {}s", e.retryAfterSeconds());
|
|
111
|
+
} catch (AirtableException e) {
|
|
112
|
+
log.error("airtable call failed", e);
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Because the hierarchy is sealed, you can also pattern-match exhaustively with a `switch` (Java 21):
|
|
117
|
+
|
|
118
|
+
```java
|
|
119
|
+
String describe(AirtableException e) {
|
|
120
|
+
return switch (e) {
|
|
121
|
+
case AirtableException.Http h -> "HTTP " + h.statusCode();
|
|
122
|
+
case AirtableException.Api a -> a.code() + ": " + a.apiMessage();
|
|
123
|
+
case AirtableException.RateLimited r -> "rate limited (" + r.retryAfterSeconds() + "s)";
|
|
124
|
+
case AirtableException.Decoding d -> "decode error";
|
|
125
|
+
case AirtableException.Network n -> "network error";
|
|
126
|
+
case AirtableException.InvalidUrl u -> "bad url";
|
|
127
|
+
case AirtableException.MissingCredentials m -> "missing credentials";
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
> [!NOTE]
|
|
133
|
+
> 429 and 5xx responses are **automatically retried** with exponential backoff (plus jitter, honoring a server `Retry-After`). `AirtableException.RateLimited` only surfaces once retries are exhausted.
|
|
134
|
+
|
|
135
|
+
#### Resource lifecycle
|
|
136
|
+
|
|
137
|
+
`Airtable` (and the underlying `AirtableClient`) implements `AutoCloseable`. A long-lived application should construct **one** `Airtable` and hold it for the process lifetime. For short-lived use, a try-with-resources block is idiomatic:
|
|
138
|
+
|
|
139
|
+
```java
|
|
140
|
+
try (var airtable = new Airtable(baseId, apiKey)) {
|
|
141
|
+
var contacts = airtable.primary().get();
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
> [!NOTE]
|
|
146
|
+
> `close()` only closes the `HttpClient` the runtime **owns** — when you inject your own `HttpClient` (via the full `AirtableClient` constructor), `close()` is a no-op and the client remains yours to manage.
|
|
147
|
+
|
|
148
|
+
#### Clearing a field
|
|
149
|
+
|
|
150
|
+
To clear a field server-side, set it to `null` on a **fetched** model and update it. Dirty-tracking diffs the model against the snapshot taken at fetch time and emits an explicit JSON `null` for the cleared field:
|
|
151
|
+
|
|
152
|
+
```java
|
|
153
|
+
var contact = airtable.primary().get("rec1234567890"); // fetched: carries a snapshot
|
|
154
|
+
contact.setSingleLineText(null);
|
|
155
|
+
airtable.primary().update(contact); // sends {"fields": {"fld...": null}}, clearing it
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
> [!IMPORTANT]
|
|
159
|
+
> This only works on a model **obtained from the table** — it has a snapshot to diff against. A freshly built model (`PrimaryModel.builder()...build()`) has no snapshot, so a `null` field is simply omitted from the create payload rather than sent as an explicit clear.
|
|
160
|
+
|
|
161
|
+
#### Filtering by formula
|
|
162
|
+
|
|
163
|
+
Filter with the per-field `f` accessor and pass the resulting formula string via `AirtableQuery.withFormula`:
|
|
164
|
+
|
|
165
|
+
```java
|
|
166
|
+
var bobs = airtable.primary()
|
|
167
|
+
.get(new AirtableQuery().withFormula(PrimaryModel.f.singleLineText.contains("Bob")));
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Text fields expose `eq`/`neq`/`contains`/`startsWith`/`endsWith`/`regexMatch` (etc.); number fields expose `eq`/`neq`/`greaterThan`/`lessThan`/`between` (etc.). Combine clauses with the `Formulas` combinators `and` / `or` / `not` / `xor`:
|
|
171
|
+
|
|
172
|
+
```java
|
|
173
|
+
var formula = Formulas.and(
|
|
174
|
+
PrimaryModel.f.singleLineText.contains("Bob"),
|
|
175
|
+
PrimaryModel.f.numberInt.greaterThan(10));
|
|
176
|
+
var results = airtable.primary().get(new AirtableQuery().withFormula(formula));
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### Upsert
|
|
180
|
+
|
|
181
|
+
`upsert(model, mergeOnFieldIds)` inserts or updates a record, matching on the given field IDs. It returns an `OrmTable.UpsertResult<T>` exposing `.model()` (the merged record) and `.wasCreated()` (insert vs update). Merge keys come from the generated `{Table}Fields` ID constants:
|
|
182
|
+
|
|
183
|
+
```java
|
|
184
|
+
var result = airtable.primary().upsert(
|
|
185
|
+
PrimaryModel.builder().primaryKey("alice@example.com").build(),
|
|
186
|
+
List.of(PrimaryFields.primaryKeyId));
|
|
187
|
+
if (result.wasCreated()) {
|
|
188
|
+
log.info("created {}", result.model().getId());
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Go
|
|
193
|
+
|
|
194
|
+
The generated Go code targets **Go 1.21+** and depends on the **standard library only** (`net/http` + `encoding/json` — no third-party modules). All files (the static runtime and the generated code) live in one flat `package airtable`, and the generator emits **no** `go.mod` — the consuming project owns its module and imports the generated package:
|
|
195
|
+
|
|
196
|
+
```go
|
|
197
|
+
import airtable "yourmodule/path/to/output"
|
|
198
|
+
|
|
199
|
+
at := airtable.NewWithBase(apiKey, baseID, 0) // cacheSeconds; 0 disables caching
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Idioms:
|
|
203
|
+
|
|
204
|
+
- **Models** are structs with `json:"fldID"` tags; optional fields are pointers (`*string`, `*float64`, …) so absent and cleared are distinguishable. Build them with the pointer helpers: `airtable.PrimaryModel{PrimaryKey: airtable.String("x")}`.
|
|
205
|
+
- **`context.Context`** is the first argument of every I/O method: `at.Primary.GetOne(ctx, id)`, `rec.Save(ctx)`.
|
|
206
|
+
- **Errors are returned, never panicked** — typed errors via `errors.As` (`*airtable.APIError`, `*airtable.RateLimitError`, …) and sentinels via `errors.Is` (`airtable.ErrNotFound`). 429/5xx are retried with backoff before surfacing.
|
|
207
|
+
- **Typed table** layer uses generics: `at.Primary` is a `Table[PrimaryModel, *PrimaryModel]`. Methods follow an explicit `*One`/`*Many` naming convention (Go has no overloading): `GetOne`/`GetMany`, `CreateOne`/`CreateMany`, `UpdateOne`/`UpdateMany`, `DeleteOne`/`DeleteMany`, plus `Upsert` and `.Dict()` for raw access. Per-model fluent `Save`/`Fetch`/`Delete` work on models bound via `at.Primary.Attach(&m)` or returned from the table.
|
|
208
|
+
- **Select options** are typed-string constants; **computed fields** decode into `*MaybeSpecialOrError[T]` (read with `.Value()`), lookups/rollups into `*VecOrValue[MaybeSpecialOrError[T]]` (read with `CleanValues`).
|
|
209
|
+
- **Filtering**: `at.Primary.GetMany(ctx, (&airtable.Query{}).WithFilterFormula(airtable.PrimaryF.PrimaryKey.Eq("alice@example.com")))`.
|
|
210
|
+
|
|
211
|
+
Generated code is `gofmt`-clean by construction; format/lint via `gofmt`/`go vet`/`golangci-lint`.
|
|
212
|
+
|
|
213
|
+
### C#
|
|
214
|
+
|
|
215
|
+
The generated C# code targets **.NET 8 / C# 12** and depends on the **base class library only** (`HttpClient` + `System.Text.Json` — no third-party packages). Every file declares the single file-scoped `namespace MyAirtable;`, and the generator emits **no** `.csproj` — the consuming project owns its build:
|
|
216
|
+
|
|
217
|
+
```csharp
|
|
218
|
+
var airtable = new Airtable(baseId, apiKey, cacheSeconds: 0); // 0 disables caching
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Idioms:
|
|
222
|
+
|
|
223
|
+
- **Models** are mutable `sealed class`es with `[JsonPropertyName("fldID")]` and nullable auto-properties. Writable fields are `{ get; set; }`; computed fields are `[JsonInclude] { get; private set; }` (decode-only). Build them with object initializers: `new PrimaryModel { PrimaryKey = "x" }`.
|
|
224
|
+
- **async/await** throughout: every I/O method is `…Async` and takes a `CancellationToken` — `await at.Primary.GetAsync(id)`, `await model.SaveAsync()`.
|
|
225
|
+
- **Errors** are an unchecked hierarchy — `catch (AirtableException)` or pattern-match a nested case (`AirtableException.ApiError`, `.RateLimitedError`, …). 429/5xx are retried with jittered backoff before surfacing.
|
|
226
|
+
- **Typed ORM is the default** on each table accessor — `at.Primary` _is_ an `OrmTable<PrimaryModel>` (reified generics, no class token), so `at.Primary.GetAsync(id)`/`CreateAsync`/`UpdateAsync`/`UpsertAsync`/`DeleteAsync` return typed models. `at.Primary.Dict` gives raw field-bag access. Per-model fluent `SaveAsync`/`FetchAsync`/`DeleteAsync`.
|
|
227
|
+
- **Select options** are C# enums with a generated per-enum `JsonConverter`; **computed fields** decode into `MaybeSpecialOrError<T>?` (read with `.ValueOrDefault`), lookups/rollups into `VecOrValue<MaybeSpecialOrError<T>>?` (read with `VecOrValue.CleanValues`).
|
|
228
|
+
- **Filtering**: `at.Primary.GetAsync(new AirtableQuery().WithFormula(PrimaryModel.F.PrimaryKey.Eq("alice@example.com")))`.
|
|
229
|
+
|
|
230
|
+
Generated code is formatted with [CSharpier](https://csharpier.com).
|
|
231
|
+
|
|
232
|
+
### C++
|
|
233
|
+
|
|
234
|
+
The generated C++ code targets **C++20** and is **header-only**: add the output folder to your include path, link **libcurl** (preinstalled on macOS/Linux), and compile the vendored timezone implementation in exactly one translation unit:
|
|
235
|
+
|
|
236
|
+
```cpp
|
|
237
|
+
// tz_impl.cpp — one file in your project (stb-style single-TU implementation)
|
|
238
|
+
#define MYAIRTABLE_TZ_IMPLEMENTATION
|
|
239
|
+
#include "static/airtable_tz.hpp"
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```cpp
|
|
243
|
+
#include "airtable.hpp"
|
|
244
|
+
myairtable::Airtable at(apiKey, /*cache_seconds=*/0); // 0 disables caching
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Idioms:
|
|
248
|
+
|
|
249
|
+
- **Models** are **aggregate structs** over a data-free CRTP behavior base: public `std::optional<T>` members, created with designated initializers — `PrimaryModel{.primary_key = "x"}` — and passed to the table's `create()`. Absent and JSON-null both decode to `std::nullopt`.
|
|
250
|
+
- **Blocking, thread-safe client**: per-request curl handles over a shared DNS/TLS-session cache; 429/5xx retried with jittered backoff before surfacing.
|
|
251
|
+
- **Errors** are exceptions rooted in `std::runtime_error` — `catch (const myairtable::AirtableException&)` or a specific subclass (`ApiError`, `RateLimitedError`, …).
|
|
252
|
+
- **Typed ORM is the default** on each table accessor — `at.primary()` _is_ an `OrmTable<PrimaryModel>`, so `get`/`get_all`/`create`/`update`/`upsert` return typed models; `.dict()` gives raw field-bag access. Per-model fluent `save()`/`fetch()`/**`remove()`** (`delete` is a C++ keyword — the one naming divergence).
|
|
253
|
+
- **Select options** are `enum class`es with generated wire serializers; **computed fields** decode into `std::optional<MaybeSpecialOrError<T>>` (read with `->value()`), lookups/rollups into `std::optional<VecOrValue<MaybeSpecialOrError<T>>>` (read with `->clean_values()`). Computed members are public but **never serialized on write** — mutating one and calling `save()` sends nothing for it (pinned by tests).
|
|
254
|
+
- **Filtering**: `at.primary().get_many(AirtableQuery{.formula = PrimaryModel::F.primary_key.eq("alice@example.com")})`. Combinators are `Formulas::and_`/`or_`/`not_` (`and`/`or`/`not` are C++ alternative tokens).
|
|
255
|
+
- Portability note: designated-initializer-over-base relies on the C++20 P1975 defect resolution; AppleClang is the CI-gated compiler, GCC/MSVC are unverified.
|
|
256
|
+
|
|
257
|
+
Generated code is formatted with [clang-format](https://clang.llvm.org/docs/ClangFormat.html) (vendored headers exempt).
|
|
258
|
+
|
|
259
|
+
## Features
|
|
260
|
+
|
|
261
|
+
The following examples are in Python, but most features are supported in every language. See notes in each section for language-specific differences.
|
|
262
|
+
|
|
263
|
+
> [!NOTE]
|
|
264
|
+
> In the examples below, `myairtable_output` stands in for _your_ generated package — the actual import path depends on the output folder you generate into.
|
|
265
|
+
|
|
266
|
+
### ORM Models
|
|
267
|
+
|
|
268
|
+
myAirtable generates strongly-typed RecordDicts and ORM classes, intended for use with the pyAirtable library.
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
# Fully-typed versions of pyAirtable's RecordDict TypedDict class
|
|
272
|
+
class ContactsRecordDict(RecordDict):
|
|
273
|
+
fields: dict[ContactsField, Any] # ContactsField is a Literal of the field names in the Contacts table
|
|
274
|
+
|
|
275
|
+
name = contact["fields"]["Name"] # your IDE will suggest "Name"
|
|
276
|
+
|
|
277
|
+
# Instance of pyAirtable's ORM
|
|
278
|
+
class ContactsModel(Model):
|
|
279
|
+
name: SingleLineTextField = SingleLineTextField(field_name="fld123")
|
|
280
|
+
address: MultilineTextField = MultilineTextField(field_name="fld789")
|
|
281
|
+
# etc
|
|
282
|
+
|
|
283
|
+
name = contact.name
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
> [!NOTE]
|
|
287
|
+
> For JavaScript & TypeScript, the ORM models are custom to myAirtable, though they still use the Airtable.js client for save/delete, and contain methods for conversion to/from Airtable.js's "Record" class. Also, they use [Zod](https://zod.dev) validation under-the-hood.
|
|
288
|
+
>
|
|
289
|
+
> For Rust, Swift, Kotlin, and Java, 100% of the code is custom to myAirtable. The convenient linked-record traversal syntax in Python and TS/JS is not (yet?) implemented in these targets — linked records are raw record-ID lists resolved through the linked table's `get`.
|
|
290
|
+
|
|
291
|
+
### Formula Builders
|
|
292
|
+
|
|
293
|
+
myAirtable also generates formula builders, for use when filtering by formula. pyAirtable already includes decent formula builders, but their options are currently limited to simple operations (e.g. =, >, <, etc), without any type-specific operations. myAirtable's formula builders include additional operations (e.g. "string contains", "date is N days ago", etc). You can access the myAirtable formula helpers from the `.f` property on each ORM class. myAirtable's formula builders are fully compatible with pyAirtable's formula builders.
|
|
294
|
+
|
|
295
|
+
```python
|
|
296
|
+
from myairtable_output import Airtable, AND, OR, ContactsModel
|
|
297
|
+
|
|
298
|
+
formula: str = AND(
|
|
299
|
+
ContactsModel.f.first_name.contains("Bob") & (ContactsModel.f.last_name == "Smith"),
|
|
300
|
+
ContactsModel.f.birthday.after().years_ago(30),
|
|
301
|
+
ContactsModel.f.birthday < "2019-04-01",
|
|
302
|
+
(ContactsModel.f.age < 10) | (ContactsModel.f.age == 12) | (ContactsModel.f.age > 15),
|
|
303
|
+
"{fld1234567890}='you can also put raw strings here'",
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
Airtable().contacts.get(formula=formula)
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
> [!NOTE]
|
|
310
|
+
> For JavaScript, TypeScript, Rust, Swift, Kotlin, and Java, the formula builders output strings, and lack the Python-specific convenience of dunder methods, but are otherwise the same. (Kotlin and Java name the equality pair `eq`/`neq` — `equals` collides with `Any.equals`/`Object.equals` on the JVM.)
|
|
311
|
+
|
|
312
|
+
### Table/CRUD Wrappers
|
|
313
|
+
|
|
314
|
+
Finally, myAirtable generates custom lightweight wrapper classes, which expose pyAirtable's CRUD methods with strongly-typed kwargs, and provide easy access to the tables through a simple interface.
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
from myairtable_output import Airtable, ContactsModel, ContactsRecordDict
|
|
318
|
+
|
|
319
|
+
airtable = Airtable()
|
|
320
|
+
|
|
321
|
+
# CRUD operations for pyAirtable ORMs
|
|
322
|
+
contact: ContactsModel = airtable.contacts.get("rec1234567890")
|
|
323
|
+
contact.name = "Bob"
|
|
324
|
+
contact.save() # pyAirtable's ORM models have handy functions like .save()
|
|
325
|
+
airtable.contacts.update(contact) # or you can use myAirtable's wrapper if you prefer that syntax
|
|
326
|
+
|
|
327
|
+
# table.get() method has kwargs for most of pyAirtable's options, which are otherwise less clear. View and Fields kwargs are typed.
|
|
328
|
+
contacts: list[ContactsModel] = airtable.contacts.get(view="Family & Friends", fields=["Name", "Age"])
|
|
329
|
+
for contact in contacts:
|
|
330
|
+
contact.age = contact.age + 1
|
|
331
|
+
contact.save()
|
|
332
|
+
|
|
333
|
+
# CRUD operations for pyAirtable RecordDicts
|
|
334
|
+
contact: ContactsRecordDict = airtable.contacts.dict.get("rec1234567890")
|
|
335
|
+
contact["fields"]["name"] = "Joe"
|
|
336
|
+
airtable.contacts.dict.update(contact)
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
> [!NOTE]
|
|
340
|
+
> For JavaScript & TypeScript, the equivalents of `.dict` are integrated into the standard CRUD operations. They will return/accept the myAirtable's `AirtableModel` classes, Airtable.js's `Record<FieldSet>` class, or a plain interface containing the json data.
|
|
341
|
+
|
|
342
|
+
### Name-locking and custom names
|
|
343
|
+
|
|
344
|
+
myAirtable optionally generates CSV files containing the names/ids of the tables and fields, including the "property name" or "model name" (for the ORM models) that they will be given in myAirtable's output. These CSV files, if present in the destination folder, will be used as the source of truth for table, model, and field names in the generated code. They can thus be used to prevent class/property names from changing unexpectedly when someone else changes a field name in Airtable, or for customizing the class/property names as they appear in code, if you prefer a different name for a given table/field. They can also be handy for resolving duplicate property name issues if that happens.
|
|
345
|
+
|
|
346
|
+
### Documentation (Markdown and HTML)
|
|
347
|
+
|
|
348
|
+
myAirtable also includes support for generating documentation for your Airtable base. There is a version in Markdown (intended for Obsidian) and in HTML (intended as a static website). This documentation includes:
|
|
349
|
+
|
|
350
|
+
- Files for every table & field, with metadata for each.
|
|
351
|
+
- Tags for each field type for easy sorting/filtering
|
|
352
|
+
- Links between related tables/fields, whether by link, lookup, rollup, or formula.
|
|
353
|
+
- Formula fields are where it really shines. It shows:
|
|
354
|
+
- A "flattened" version of the formula. If the formula references another formula (etc), the whole thing is shown.
|
|
355
|
+
- A formatted and syntax-colored version of the formula, for easy readability.
|
|
356
|
+
- A [Mermaid](https://mermaid.ai) representation of the formula.
|
|
357
|
+
|
|
358
|
+
### Extra Goodies (because I can't stop coding...)
|
|
359
|
+
|
|
360
|
+
- All the types: just about everything from the schema has a constant/dict/type for convenience. Want an array of the options for a select field? How about a map between field ids and names? Or perhaps a union type representing all table names? It's all in there.
|
|
361
|
+
- Convenience functions to:
|
|
362
|
+
- build an Airtable URL for base/table/view/record
|
|
363
|
+
- get the schema, either static (the one used to build the code) or live (from Airtable's API)
|
|
364
|
+
- Optional caching
|
|
365
|
+
- Optional runtime formula evaluation: if enabled, formula fields have their formula transpiled to native code, to allow runtime (re)evaluation. Supports nearly all formulas (can't do LAST_MODIFIED_TIME or CREATED_TIME).
|
|
366
|
+
- MCP Server: Allows agents to analyze your Airtable schema
|
|
367
|
+
|
|
368
|
+
## Getting Started
|
|
369
|
+
|
|
370
|
+
Requires Python 3.12+.
|
|
371
|
+
|
|
372
|
+
### Install
|
|
373
|
+
|
|
374
|
+
To run the code generator, install with the `cli` extra:
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
uv tool install "myairtable[cli]"
|
|
378
|
+
myairtable --help
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Then provide credentials, either as flags (`--base-id`, `--api-key`) or via a `.env`
|
|
382
|
+
file in the working directory:
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
AIRTABLE_API_KEY=your_airtable_api_key_here
|
|
386
|
+
AIRTABLE_BASE_ID=app1234567890
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Extras
|
|
390
|
+
|
|
391
|
+
The package splits along what you actually need, so importing the analysis layer
|
|
392
|
+
doesn't drag in the whole generator:
|
|
393
|
+
|
|
394
|
+
| Install | Gets you |
|
|
395
|
+
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
396
|
+
| `myairtable` | The analysis layer only — `myairtable.schema_tools` (28 read-only tools over the public meta API), for importing into your own code |
|
|
397
|
+
| `myairtable[cli]` | The above plus the code generator for all 11 targets (the `myairtable` command) |
|
|
398
|
+
| `myairtable[mcp]` | The above plus the MCP server |
|
|
399
|
+
|
|
400
|
+
### Developing on myAirtable itself
|
|
401
|
+
|
|
402
|
+
1. Clone the repo
|
|
403
|
+
2. [Install uv](https://docs.astral.sh/uv/getting-started/installation/)
|
|
404
|
+
3. `uv sync` — installs the project editable, with every extra and dev tool
|
|
405
|
+
4. Add the `.env` above
|
|
406
|
+
5. `uv run myairtable --help`
|
|
407
|
+
|
|
408
|
+
## MCP Server
|
|
409
|
+
|
|
410
|
+
myAirtable includes an MCP server that exposes read-only tools for Airtable schema introspection and analysis.
|
|
411
|
+
|
|
412
|
+
### Setup
|
|
413
|
+
|
|
414
|
+
Add the following to your MCP client config (e.g. `claude_desktop_config.json` for Claude Desktop, or `.claude/settings.json` for Claude Code):
|
|
415
|
+
|
|
416
|
+
```json
|
|
417
|
+
{
|
|
418
|
+
"mcpServers": {
|
|
419
|
+
"myairtable": {
|
|
420
|
+
"command": "uv",
|
|
421
|
+
"args": ["run", "--directory", "/path/to/myairtable", "python", "-m", "myairtable.mcp_server"],
|
|
422
|
+
"env": {
|
|
423
|
+
"AIRTABLE_API_KEY": "your_airtable_api_key_here",
|
|
424
|
+
"AIRTABLE_BASE_ID": "app1234567890"
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
If you have a `.env` file configured (see step 4 above), you can omit the `env` block.
|
|
432
|
+
|
|
433
|
+
### Tools on the CLI
|
|
434
|
+
|
|
435
|
+
Every MCP tool is also a CLI subcommand under `myairtable tools` — handy for scripting,
|
|
436
|
+
piping to `jq`, or testing without an MCP client:
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
myairtable tools list-tables # public meta-API tools
|
|
440
|
+
myairtable tools transpile Jobs "Total" --language python
|
|
441
|
+
myairtable tools --help # list all commands
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Output is JSON by default (`--pretty` for rich rendering). Add `--save` (before the
|
|
445
|
+
subcommand) to offload large results to `.data/tools/` and print the envelope, mirroring the
|
|
446
|
+
MCP server. The same `schema_tools.py` functions back both the MCP tools and these commands.
|
|
447
|
+
|
|
448
|
+
### Large results are saved to disk
|
|
449
|
+
|
|
450
|
+
Many tools can return large payloads (whole-base scans, full schema dumps). When a result
|
|
451
|
+
exceeds the inline limit (default 16 KB; override with `MYAIRTABLE_INLINE_MAX_BYTES`), the
|
|
452
|
+
**full** result is written to a gitignored `.data/tools/<tool>__<args>.json` and the caller
|
|
453
|
+
receives a small envelope instead:
|
|
454
|
+
|
|
455
|
+
```json
|
|
456
|
+
{ "saved_to": "...", "bytes": 412934, "record_count": 287,
|
|
457
|
+
"summary": { ... }, "schema": { ...compact shape skeleton... }, "note": "..." }
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
`schema` is a depth-capped structural skeleton of the file (keys → type tags, arrays → length +
|
|
461
|
+
element shape) — enough to `jq`/`grep` the file without re-running the tool. This applies to
|
|
462
|
+
**all** MCP tools via a server middleware. From the CLI, add `--save` (e.g.
|
|
463
|
+
`myairtable tools --save list-automations`) to exercise the same path. Note: `audit_shares`
|
|
464
|
+
writes share-URL tokens to that local file.
|
|
465
|
+
|
|
466
|
+
## License
|
|
467
|
+
|
|
468
|
+
[MIT](LICENSE)
|