Skip to content

Commit 02571b6

Browse files
author
Sergii Solonyna
committed
Init commit
0 parents  commit 02571b6

67 files changed

Lines changed: 8328 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: ["**"]
6+
pull_request:
7+
branches: ["**"]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
analyze:
15+
name: Analyze
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- uses: dart-lang/setup-dart@v1
21+
with:
22+
sdk: stable
23+
24+
- name: Install dependencies
25+
run: dart pub get
26+
27+
- name: Verify formatting
28+
run: dart format --output=none --set-exit-if-changed .
29+
30+
- name: Analyze project source
31+
run: dart analyze --fatal-infos
32+
33+
test:
34+
name: Test
35+
runs-on: ubuntu-latest
36+
needs: analyze
37+
steps:
38+
- uses: actions/checkout@v4
39+
40+
- uses: dart-lang/setup-dart@v1
41+
with:
42+
sdk: stable
43+
44+
- name: Install dependencies
45+
run: dart pub get
46+
47+
- name: Run tests
48+
run: dart test --reporter=expanded
49+
50+
publish-dry-run:
51+
name: Publish (dry run)
52+
runs-on: ubuntu-latest
53+
needs: test
54+
steps:
55+
- uses: actions/checkout@v4
56+
57+
- uses: dart-lang/setup-dart@v1
58+
with:
59+
sdk: stable
60+
61+
- name: Install dependencies
62+
run: dart pub get
63+
64+
- name: Verify publish readiness
65+
run: dart pub publish --dry-run

.github/workflows/publish.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: Publish to pub.dev
2+
3+
on:
4+
push:
5+
tags:
6+
- "v[0-9]+.[0-9]+.[0-9]+"
7+
8+
jobs:
9+
validate:
10+
name: Validate tag version
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Extract tag version
16+
id: tag
17+
run: |
18+
TAG="${GITHUB_REF_NAME}"
19+
VERSION="${TAG#v}"
20+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
21+
22+
- name: Read pubspec version
23+
id: pubspec
24+
run: |
25+
VERSION=$(grep '^version:' pubspec.yaml | awk '{print $2}' | tr -d "'\"")
26+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
27+
28+
- name: Assert tag matches pubspec.yaml
29+
run: |
30+
TAG_VERSION="${{ steps.tag.outputs.version }}"
31+
PUBSPEC_VERSION="${{ steps.pubspec.outputs.version }}"
32+
echo "Tag version: $TAG_VERSION"
33+
echo "pubspec version: $PUBSPEC_VERSION"
34+
if [ "$TAG_VERSION" != "$PUBSPEC_VERSION" ]; then
35+
echo "::error::Tag v$TAG_VERSION does not match pubspec.yaml version $PUBSPEC_VERSION"
36+
exit 1
37+
fi
38+
echo "Version match confirmed: $TAG_VERSION"
39+
40+
analyze:
41+
name: Analyze
42+
runs-on: ubuntu-latest
43+
needs: validate
44+
steps:
45+
- uses: actions/checkout@v4
46+
47+
- uses: dart-lang/setup-dart@v1
48+
with:
49+
sdk: stable
50+
51+
- name: Install dependencies
52+
run: dart pub get
53+
54+
- name: Verify formatting
55+
run: dart format --output=none --set-exit-if-changed .
56+
57+
- name: Analyze project source
58+
run: dart analyze --fatal-infos
59+
60+
test:
61+
name: Test
62+
runs-on: ubuntu-latest
63+
needs: validate
64+
steps:
65+
- uses: actions/checkout@v4
66+
67+
- uses: dart-lang/setup-dart@v1
68+
with:
69+
sdk: stable
70+
71+
- name: Install dependencies
72+
run: dart pub get
73+
74+
- name: Run tests
75+
run: dart test --reporter=expanded
76+
77+
publish:
78+
name: Publish
79+
runs-on: ubuntu-latest
80+
needs: [analyze, test]
81+
permissions:
82+
id-token: write
83+
environment: pub.dev
84+
steps:
85+
- uses: actions/checkout@v4
86+
87+
- uses: dart-lang/setup-dart@v1
88+
with:
89+
sdk: stable
90+
91+
- name: Install dependencies
92+
run: dart pub get
93+
94+
- name: Publish to pub.dev
95+
run: dart pub publish --force

.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Dart/Flutter
2+
.dart_tool/
3+
build/
4+
.packages
5+
pubspec.lock
6+
7+
# OpenAPI spec (downloaded locally, not committed)
8+
openapi.json
9+
docs-openapi.json
10+
11+
# IDE
12+
.idea/
13+
.vscode/
14+
*.iml
15+
16+
# OS
17+
.DS_Store
18+
Thumbs.db
19+
20+
# Coverage
21+
coverage/

CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
## [1.0.0] - 2026-02-20
11+
12+
### Added
13+
- `AstrologyClient` with 16 category sub-clients: `data`, `charts`,
14+
`horoscope`, `analysis`, `glossary`, `astrocartography`, `chinese`,
15+
`eclipses`, `lunar`, `numerology`, `tarot`, `traditional`, `fixedStars`,
16+
`insights`, `svg`, and `enhanced`.
17+
- `InsightsClient` with 5 typed sub-clients: `relationship`, `pet`,
18+
`wellness`, `financial`, and `business`.
19+
- `AstrologyClientConfig` with configurable API key, base URL, timeout,
20+
debug mode, and custom logger.
21+
- `RetryConfig` for automatic retry on transient errors with configurable
22+
attempt count, delay, and retry status codes.
23+
- `RequestOptions` for per-request headers, query parameters, timeout
24+
override, and Dio `CancelToken` support.
25+
- `AstrologyException` with HTTP status code, error code, and detail fields.
26+
- `HttpHelper` abstract interface for mock-based unit testing.
27+
- Dio-based `DioHttpClient` with Bearer token injection, automatic response
28+
unwrapping, and retry logic.
29+
- SVG chart support via `SvgClient` returning raw `String`.
30+
- `GenericResponse` for complex or schema-variable API responses.
31+
- Request and response model classes for all 16 API categories.
32+
- Enum types: `Language`, `HouseSystem`, `ZodiacType`, `Tradition`,
33+
`PerspectiveType`, `DetailLevel`.
34+
35+
[Unreleased]: https://github.com/astro-api/astroapi-flutter/compare/v1.0.0...HEAD
36+
[1.0.0]: https://github.com/astro-api/astroapi-flutter/releases/tag/v1.0.0

CLAUDE.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# AstroAPI Flutter/Dart SDK
2+
3+
Dart/Flutter SDK for the Astrology API v3. No code generation (no freezed/json_serializable) — uses plain Dart classes with manual `toJson()`.
4+
5+
## Setup
6+
7+
```bash
8+
dart pub get
9+
```
10+
11+
## Development Commands
12+
13+
```bash
14+
# Install dependencies
15+
dart pub get
16+
17+
# Analyze code
18+
dart analyze
19+
20+
# Run tests
21+
dart test
22+
23+
# Run tests with coverage
24+
dart test --coverage=coverage
25+
```
26+
27+
## Architecture
28+
29+
```
30+
lib/
31+
astroapi.dart # Barrel export (public API)
32+
src/
33+
client/astrology_client.dart # Main AstrologyClient class
34+
config/astrology_client_config.dart # Config, RetryConfig, RequestOptions
35+
http/
36+
http_helper.dart # Abstract HttpHelper interface
37+
dio_http_client.dart # Dio-based implementation with retry
38+
errors/astrology_exception.dart # AstrologyException
39+
categories/ # 16 category clients
40+
models/
41+
requests/ # Request types (toJson())
42+
responses/ # Response types (fromJson())
43+
enums/ # Language, HouseSystem, etc.
44+
```
45+
46+
## Usage Example
47+
48+
```dart
49+
import 'package:astroapi/astroapi.dart';
50+
51+
final client = AstrologyClient(
52+
AstrologyClientConfig(
53+
apiKey: 'your-api-key',
54+
timeout: 15000,
55+
retry: RetryConfig(attempts: 3, delayMs: 500),
56+
),
57+
);
58+
59+
// Get planetary positions
60+
final positions = await client.data.getPositions(
61+
PlanetaryPositionsRequest(
62+
subject: Subject(
63+
birthData: BirthData(
64+
year: 1990, month: 5, day: 11,
65+
hour: 14, minute: 30,
66+
city: 'London', countryCode: 'GB',
67+
),
68+
),
69+
),
70+
);
71+
print(positions.positions[0].sign);
72+
73+
// Get natal chart
74+
final chart = await client.charts.getNatalChart(
75+
NatalChartRequest(subject: subject),
76+
);
77+
78+
// Insights sub-clients
79+
final compat = await client.insights.relationship.getCompatibility(
80+
CompatibilityRequest(subjects: [subject1, subject2]),
81+
);
82+
83+
// SVG chart
84+
final svg = await client.svg.getNatalChartSvg(
85+
NatalChartSvgRequest(subject: subject),
86+
);
87+
```
88+
89+
## Key Design Decisions
90+
91+
- **No code generation**: Plain Dart classes instead of freezed/json_serializable for simplicity and faster compilation
92+
- **GenericResponse**: Complex API responses use `GenericResponse` (wraps `Map<String, dynamic>`) with typed fields for commonly-used properties
93+
- **HttpHelper abstraction**: The `HttpHelper` interface enables easy mocking in tests with `mocktail`
94+
- **Retry logic**: Built into `DioHttpClient`, configurable via `RetryConfig`
95+
- **SVG responses**: `SvgClient` returns `String` directly instead of JSON
96+
- **InsightsClient**: Has 5 sub-clients (relationship, pet, wellness, financial, business)
97+
98+
## Testing
99+
100+
Uses `mocktail` to mock `HttpHelper`:
101+
102+
```dart
103+
class MockHttpHelper extends Mock implements HttpHelper {}
104+
105+
final client = DataClient(MockHttpHelper());
106+
```

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Astro API
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 commit comments

Comments
 (0)