Skip to content

Commit 1c4fe8f

Browse files
committed
feat: initial Turso Elixir client library
Complete implementation of Turso Cloud Platform API client with: - Full API coverage (databases, groups, organizations, tokens, audit logs) - Client-based architecture following modern Elixir patterns - Comprehensive error handling with helper functions - Built-in mock server for testing - NimbleOptions for parameter validation - Streaming support for large datasets - Zero-dependency configuration with configurable HTTP options - MIT licensed with full documentation
0 parents  commit 1c4fe8f

32 files changed

+4965
-0
lines changed

.credo.exs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
%{
2+
configs: [
3+
%{
4+
name: "default",
5+
files: %{
6+
included: ["lib/", "test/"],
7+
excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"]
8+
},
9+
requires: [],
10+
strict: true,
11+
color: true,
12+
checks: [
13+
#
14+
## Consistency Checks
15+
#
16+
{Credo.Check.Consistency.ExceptionNames, []},
17+
{Credo.Check.Consistency.LineEndings, []},
18+
{Credo.Check.Consistency.ParameterPatternMatching, []},
19+
{Credo.Check.Consistency.SpaceAroundOperators, []},
20+
{Credo.Check.Consistency.SpaceInParentheses, []},
21+
{Credo.Check.Consistency.TabsOrSpaces, []},
22+
23+
#
24+
## Design Checks
25+
#
26+
{Credo.Check.Design.AliasUsage,
27+
[priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]},
28+
{Credo.Check.Design.TagTODO, [exit_status: 2]},
29+
{Credo.Check.Design.TagFIXME, []},
30+
31+
#
32+
## Readability Checks
33+
#
34+
{Credo.Check.Readability.AliasOrder, []},
35+
{Credo.Check.Readability.FunctionNames, []},
36+
{Credo.Check.Readability.LargeNumbers, []},
37+
{Credo.Check.Readability.MaxLineLength, [priority: :low, max_length: 120]},
38+
{Credo.Check.Readability.ModuleAttributeNames, []},
39+
{Credo.Check.Readability.ModuleDoc, []},
40+
{Credo.Check.Readability.ModuleNames, []},
41+
{Credo.Check.Readability.ParenthesesInCondition, []},
42+
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, []},
43+
{Credo.Check.Readability.PredicateFunctionNames, []},
44+
{Credo.Check.Readability.PreferImplicitTry, []},
45+
{Credo.Check.Readability.RedundantBlankLines, []},
46+
{Credo.Check.Readability.Semicolons, []},
47+
{Credo.Check.Readability.SpaceAfterCommas, []},
48+
{Credo.Check.Readability.StringSigils, []},
49+
{Credo.Check.Readability.TrailingBlankLine, []},
50+
{Credo.Check.Readability.TrailingWhiteSpace, []},
51+
{Credo.Check.Readability.UnnecessaryAliasExpansion, []},
52+
{Credo.Check.Readability.VariableNames, []},
53+
{Credo.Check.Readability.Specs, []},
54+
55+
#
56+
## Refactoring Opportunities
57+
#
58+
{Credo.Check.Refactor.CondStatements, []},
59+
{Credo.Check.Refactor.CyclomaticComplexity, []},
60+
{Credo.Check.Refactor.FunctionArity, []},
61+
{Credo.Check.Refactor.LongQuoteBlocks, []},
62+
{Credo.Check.Refactor.MapInto, false},
63+
{Credo.Check.Refactor.MatchInCondition, []},
64+
{Credo.Check.Refactor.NegatedConditionsInUnless, []},
65+
{Credo.Check.Refactor.NegatedConditionsWithElse, []},
66+
{Credo.Check.Refactor.Nesting, []},
67+
{Credo.Check.Refactor.UnlessWithElse, []},
68+
{Credo.Check.Refactor.WithSingleClause, []},
69+
70+
#
71+
## Warnings
72+
#
73+
{Credo.Check.Warning.ApplicationConfigInModuleAttribute, []},
74+
{Credo.Check.Warning.BoolOperationOnSameValues, []},
75+
{Credo.Check.Warning.ExpensiveEmptyEnumCheck, []},
76+
{Credo.Check.Warning.IExPry, []},
77+
{Credo.Check.Warning.IoInspect, false},
78+
{Credo.Check.Warning.LazyLogging, false},
79+
{Credo.Check.Warning.MixEnv, false},
80+
{Credo.Check.Warning.OperationOnSameValues, []},
81+
{Credo.Check.Warning.OperationWithConstantResult, []},
82+
{Credo.Check.Warning.RaiseInsideRescue, []},
83+
{Credo.Check.Warning.UnusedEnumOperation, []},
84+
{Credo.Check.Warning.UnusedFileOperation, []},
85+
{Credo.Check.Warning.UnusedKeywordOperation, []},
86+
{Credo.Check.Warning.UnusedListOperation, []},
87+
{Credo.Check.Warning.UnusedPathOperation, []},
88+
{Credo.Check.Warning.UnusedRegexOperation, []},
89+
{Credo.Check.Warning.UnusedStringOperation, []},
90+
{Credo.Check.Warning.UnusedTupleOperation, []},
91+
{Credo.Check.Warning.UnsafeExec, []}
92+
]
93+
}
94+
]
95+
}

.formatter.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Used by "mix format"
2+
[
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4+
]

.github/workflows/ci.yml

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
env:
10+
MIX_ENV: test
11+
12+
jobs:
13+
# Single test job using mise
14+
test:
15+
name: Test and Lint
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Install mise and tools
22+
uses: jdx/mise-action@v3
23+
with:
24+
install: true
25+
cache: true
26+
github_token: ${{ secrets.GITHUB_TOKEN }}
27+
28+
- name: Cache dependencies
29+
uses: actions/cache@v4
30+
with:
31+
path: |
32+
deps/
33+
_build/
34+
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}-${{ hashFiles('mise.toml') }}
35+
restore-keys: |
36+
${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}-
37+
${{ runner.os }}-mix-
38+
39+
- name: Install dependencies
40+
run: mix deps.get
41+
42+
- name: Check code formatting
43+
run: mix format --check-formatted
44+
45+
- name: Check for unused dependencies
46+
run: mix deps.unlock --check-unused
47+
48+
- name: Run Credo
49+
run: mix credo --strict
50+
51+
- name: Compile application
52+
run: mix compile --warnings-as-errors
53+
54+
- name: Run tests
55+
run: mix test --warnings-as-errors
56+
57+
- name: Generate coverage report
58+
run: mix coveralls.github
59+
env:
60+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61+
62+
- name: Upload coverage artifacts
63+
uses: actions/upload-artifact@v4
64+
with:
65+
name: coverage-report
66+
path: cover/
67+
68+
69+
# Pre-commit validation (parallel with test)
70+
pre-commit:
71+
name: Pre-commit Checks
72+
runs-on: ubuntu-latest
73+
steps:
74+
- name: Checkout code
75+
uses: actions/checkout@v4
76+
77+
- name: Install mise and tools
78+
uses: jdx/mise-action@v3
79+
with:
80+
install: true
81+
cache: true
82+
github_token: ${{ secrets.GITHUB_TOKEN }}
83+
84+
- name: Cache dependencies
85+
uses: actions/cache@v4
86+
with:
87+
path: |
88+
deps/
89+
_build/
90+
key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-${{ hashFiles('lib/**/*.ex') }}-${{ hashFiles('test/**/*.exs') }}-${{ hashFiles('mise.toml') }}
91+
restore-keys: |
92+
${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-${{ hashFiles('lib/**/*.ex') }}-${{ hashFiles('test/**/*.exs') }}-
93+
${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-
94+
${{ runner.os }}-mix-
95+
96+
- name: Install dependencies
97+
run: |
98+
mix local.hex --force
99+
mix deps.get
100+
101+
- name: Run pre-commit
102+
uses: pre-commit/action@v3.0.1
103+
104+
# Documentation generation (depends on successful test)
105+
docs:
106+
name: Documentation
107+
runs-on: ubuntu-latest
108+
needs: test
109+
env:
110+
MIX_ENV: dev
111+
112+
steps:
113+
- name: Checkout code
114+
uses: actions/checkout@v4
115+
116+
- name: Install mise and tools
117+
uses: jdx/mise-action@v3
118+
with:
119+
install: true
120+
cache: true
121+
github_token: ${{ secrets.GITHUB_TOKEN }}
122+
123+
- name: Cache dependencies
124+
uses: actions/cache@v4
125+
with:
126+
path: |
127+
deps/
128+
_build/
129+
key: ${{ runner.os }}-mix-dev-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-${{ hashFiles('mise.toml') }}
130+
restore-keys: |
131+
${{ runner.os }}-mix-dev-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-
132+
${{ runner.os }}-mix-dev-
133+
134+
- name: Install dependencies
135+
run: mix deps.get
136+
137+
- name: Generate documentation
138+
run: mix docs
139+
140+
- name: Upload documentation
141+
if: github.ref == 'refs/heads/main'
142+
uses: actions/upload-artifact@v4
143+
with:
144+
name: documentation
145+
path: doc/
146+
147+
# Security audit (parallel with test)
148+
security:
149+
name: Security Audit
150+
runs-on: ubuntu-latest
151+
152+
steps:
153+
- name: Checkout code
154+
uses: actions/checkout@v4
155+
156+
- name: Install mise and tools
157+
uses: jdx/mise-action@v3
158+
with:
159+
install: true
160+
cache: true
161+
github_token: ${{ secrets.GITHUB_TOKEN }}
162+
163+
- name: Cache dependencies
164+
uses: actions/cache@v4
165+
with:
166+
path: |
167+
deps/
168+
_build/
169+
key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-${{ hashFiles('mise.toml') }}
170+
restore-keys: |
171+
${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-
172+
${{ runner.os }}-mix-
173+
174+
- name: Install dependencies
175+
run: mix deps.get
176+
177+
- name: Check for security vulnerabilities
178+
run: mix deps.audit
179+
180+
# Dependency analysis (parallel with test)
181+
dependency_check:
182+
name: Dependency Analysis
183+
runs-on: ubuntu-latest
184+
185+
steps:
186+
- name: Checkout code
187+
uses: actions/checkout@v4
188+
189+
- name: Install mise and tools
190+
uses: jdx/mise-action@v3
191+
with:
192+
install: true
193+
cache: true
194+
github_token: ${{ secrets.GITHUB_TOKEN }}
195+
196+
- name: Cache dependencies
197+
uses: actions/cache@v4
198+
with:
199+
path: |
200+
deps/
201+
_build/
202+
key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-${{ hashFiles('mise.toml') }}
203+
restore-keys: |
204+
${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}-
205+
${{ runner.os }}-mix-
206+
207+
- name: Install dependencies
208+
run: mix deps.get
209+
210+
- name: Check dependency status
211+
run: mix hex.outdated
212+
213+
# CI Results summary (inspired by WebSocket Bridge)
214+
results:
215+
name: CI Results
216+
runs-on: ubuntu-latest
217+
needs: [test, pre-commit, docs, security, dependency_check]
218+
if: always()
219+
220+
steps:
221+
- name: Check job results
222+
run: |
223+
echo "Test job result: ${{ needs.test.result }}"
224+
echo "Pre-commit job result: ${{ needs.pre-commit.result }}"
225+
echo "Docs job result: ${{ needs.docs.result }}"
226+
echo "Security job result: ${{ needs.security.result }}"
227+
echo "Dependency check result: ${{ needs.dependency_check.result }}"
228+
229+
if [[ "${{ needs.test.result }}" == "failure" || "${{ needs.pre-commit.result }}" == "failure" || "${{ needs.docs.result }}" == "failure" || "${{ needs.security.result }}" == "failure" || "${{ needs.dependency_check.result }}" == "failure" ]]; then
230+
echo "❌ CI Pipeline Failed"
231+
exit 1
232+
else
233+
echo "✅ CI Pipeline Passed"
234+
fi

0 commit comments

Comments
 (0)