Skip to content

Commit 314189c

Browse files
authored
Merge pull request #151 from tharropoulos/v30.0
Add support for v30.0 and add missing features from v0.25+
2 parents 3aec5b4 + 175aff5 commit 314189c

Some content is hidden

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

49 files changed

+3035
-12
lines changed

.github/workflows/dart.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,26 @@ jobs:
1616
runs-on: ubuntu-latest
1717

1818
steps:
19+
- name: Start Typesense
20+
run: |
21+
docker run -d \
22+
-p 8108:8108 \
23+
--name typesense \
24+
-v /tmp/typesense-data:/data \
25+
-v /tmp/typesense-analytics-data:/analytics-data \
26+
typesense/typesense:30.0.rca37 \
27+
--api-key=xyz \
28+
--data-dir=/data \
29+
--enable-search-analytics=true \
30+
--analytics-dir=/analytics-data \
31+
--analytics-flush-interval=60 \
32+
--analytics-minute-rate-limit=50 \
33+
--enable-cors
34+
35+
- name: Wait for Typesense
36+
run: |
37+
timeout 20 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8108/health)" != "200" ]]; do sleep 1; done' || false
38+
1939
- uses: actions/checkout@v3
2040

2141
# Note: This workflow uses the latest stable version of the Dart SDK.

lib/src/analytics.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import 'services/api_call.dart';
2+
import 'analytics_rules.dart';
3+
import 'analytics_rule.dart';
4+
import 'analytics_events.dart';
5+
6+
class Analytics {
7+
final ApiCall _apiCall;
8+
final AnalyticsRules _rules;
9+
final AnalyticsEvents _events;
10+
final _individualRules = <String, AnalyticsRule>{};
11+
12+
Analytics(ApiCall apiCall)
13+
: _apiCall = apiCall,
14+
_rules = AnalyticsRules(apiCall),
15+
_events = AnalyticsEvents(apiCall);
16+
17+
AnalyticsRules rules() => _rules;
18+
19+
AnalyticsRule rule(String name) {
20+
if (!_individualRules.containsKey(name)) {
21+
_individualRules[name] = AnalyticsRule(name, _apiCall);
22+
}
23+
return _individualRules[name]!;
24+
}
25+
26+
AnalyticsEvents events() => _events;
27+
}

lib/src/analytics_events.dart

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import 'models/models.dart';
2+
import 'services/api_call.dart';
3+
4+
class AnalyticsEvents {
5+
final ApiCall _apiCall;
6+
static const String eventsPath = '/analytics/events';
7+
static const String flushPath = '/analytics/flush';
8+
static const String statusPath = '/analytics/status';
9+
10+
AnalyticsEvents(ApiCall apiCall) : _apiCall = apiCall;
11+
12+
Future<AnalyticsEventCreateResponse> create(
13+
AnalyticsEventCreateSchema event) async {
14+
final response =
15+
await _apiCall.post(eventsPath, bodyParameters: event.toJson());
16+
return AnalyticsEventCreateResponse.fromJson(response);
17+
}
18+
19+
Future<AnalyticsEventsRetrieveSchema> retrieve({
20+
required String userId,
21+
required String name,
22+
required int n,
23+
}) async {
24+
final response = await _apiCall.get(
25+
eventsPath,
26+
queryParams: {
27+
'user_id': userId,
28+
'name': name,
29+
'n': n.toString(),
30+
},
31+
);
32+
return AnalyticsEventsRetrieveSchema.fromJson(response);
33+
}
34+
35+
Future<AnalyticsEventCreateResponse> flush() async {
36+
final response = await _apiCall.post(flushPath, bodyParameters: {});
37+
return AnalyticsEventCreateResponse.fromJson(response);
38+
}
39+
40+
Future<AnalyticsStatus> status() async {
41+
final response = await _apiCall.get(statusPath);
42+
return AnalyticsStatus.fromJson(response);
43+
}
44+
}

lib/src/analytics_rule.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'models/models.dart';
2+
import 'services/api_call.dart';
3+
import 'analytics_rules.dart';
4+
5+
class AnalyticsRule {
6+
final String _name;
7+
final ApiCall _apiCall;
8+
9+
AnalyticsRule(String name, ApiCall apiCall)
10+
: _name = name,
11+
_apiCall = apiCall;
12+
13+
Future<AnalyticsRuleSchema> retrieve() async {
14+
final response = await _apiCall.get(_endpointPath);
15+
return AnalyticsRuleSchema.fromJson(response);
16+
}
17+
18+
Future<AnalyticsRuleDeleteSchema> delete() async {
19+
final response = await _apiCall.delete(_endpointPath);
20+
return AnalyticsRuleDeleteSchema.fromJson(response);
21+
}
22+
23+
String get _endpointPath =>
24+
'${AnalyticsRules.resourcepath}/${Uri.encodeComponent(_name)}';
25+
}

lib/src/analytics_rules.dart

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import 'dart:convert';
2+
3+
import 'models/models.dart';
4+
import 'services/api_call.dart';
5+
import 'analytics_rule.dart';
6+
7+
class AnalyticsRules {
8+
final ApiCall _apiCall;
9+
static const String resourcepath = '/analytics/rules';
10+
final _individualRules = <String, AnalyticsRule>{};
11+
12+
AnalyticsRules(ApiCall apiCall) : _apiCall = apiCall;
13+
14+
/// Creates a single analytics rule.
15+
Future<AnalyticsRuleSchema> create(AnalyticsRuleCreateSchema rule) async {
16+
final response = await _apiCall.post(
17+
resourcepath,
18+
bodyParameters: rule.toJson(),
19+
);
20+
return AnalyticsRuleSchema.fromJson(
21+
Map<String, dynamic>.from(response as Map),
22+
);
23+
}
24+
25+
/// Creates multiple analytics rules.
26+
Future<List<AnalyticsRuleSchema>> createMany(
27+
List<AnalyticsRuleCreateSchema> rules) async {
28+
final body = rules.map((item) => item.toJson()).toList();
29+
final encodedBody = json.encode(body);
30+
final response = await _apiCall.sendList((node) => node.client!.post(
31+
_apiCall.getRequestUri(node, resourcepath),
32+
headers: _apiCall.defaultHeaders,
33+
body: encodedBody,
34+
));
35+
return response.map((item) {
36+
return AnalyticsRuleSchema.fromJson(
37+
Map<String, dynamic>.from(item as Map),
38+
);
39+
}).toList();
40+
}
41+
42+
Future<List<AnalyticsRuleSchema>> retrieve({String? ruleTag}) async {
43+
final query = <String, String>{};
44+
if (ruleTag != null) {
45+
query['rule_tag'] = ruleTag;
46+
}
47+
final response = await _apiCall.getList(
48+
resourcepath,
49+
queryParams: query.isEmpty ? null : query,
50+
);
51+
return response
52+
.map((item) =>
53+
AnalyticsRuleSchema.fromJson(Map<String, dynamic>.from(item)))
54+
.toList();
55+
}
56+
57+
Future<AnalyticsRuleSchema> upsert(
58+
String ruleName, AnalyticsRuleUpsertSchema update) async {
59+
final response = await _apiCall.put(
60+
'$resourcepath/${Uri.encodeComponent(ruleName)}',
61+
bodyParameters: update.toJson(),
62+
);
63+
return AnalyticsRuleSchema.fromJson(response);
64+
}
65+
66+
AnalyticsRule operator [](String ruleName) {
67+
if (!_individualRules.containsKey(ruleName)) {
68+
_individualRules[ruleName] = AnalyticsRule(ruleName, _apiCall);
69+
}
70+
return _individualRules[ruleName]!;
71+
}
72+
}

lib/src/client.dart

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@ import 'presets.dart';
2020
import 'metrics.dart';
2121
import 'operations.dart';
2222
import 'multi_search.dart';
23+
import 'stopword.dart';
24+
import 'stopwords.dart';
25+
import 'curation_sets.dart';
26+
import 'curation_set.dart';
27+
import 'synonym_sets.dart';
28+
import 'synonym_set.dart';
29+
import 'stemming.dart';
30+
import 'conversations_models.dart';
31+
import 'conversation_model.dart';
32+
import 'nl_search_models.dart';
33+
import 'nl_search_model.dart';
34+
import 'conversations.dart';
35+
import 'conversation.dart';
36+
import 'analytics.dart';
2337

2438
class Client {
2539
final Configuration config;
@@ -35,10 +49,22 @@ class Client {
3549
final Metrics metrics;
3650
final Operations operations;
3751
final MultiSearch multiSearch;
52+
final Stopwords stopwords;
53+
final CurationSets curationSets;
54+
final SynonymSets synonymSets;
55+
final Stemming stemming;
56+
final ConversationsModels conversationsModels;
57+
final NLSearchModels nlSearchModels;
58+
final Conversations conversations;
59+
final Analytics analytics;
3860
final _individualCollections = HashMap<String, Collection>(),
3961
_individualAliases = HashMap<String, Alias>(),
4062
_individualKeys = HashMap<int, Key>(),
41-
_individualPresets = HashMap<String, Preset>();
63+
_individualPresets = HashMap<String, Preset>(),
64+
_individualStopwords = HashMap<String, Stopword>(),
65+
_individualCurationSets = HashMap<String, CurationSet>(),
66+
_individualSynonymSets = HashMap<String, SynonymSet>();
67+
final _individualConversations = HashMap<String, Conversation>();
4268

4369
Client._(
4470
this.config,
@@ -53,7 +79,15 @@ class Client {
5379
this.health,
5480
this.metrics,
5581
this.operations,
56-
this.multiSearch);
82+
this.multiSearch,
83+
this.stopwords,
84+
this.curationSets,
85+
this.synonymSets,
86+
this.stemming,
87+
this.conversationsModels,
88+
this.nlSearchModels,
89+
this.conversations,
90+
this.analytics);
5791

5892
factory Client(Configuration config) {
5993
// ApiCall, DocumentsApiCall, and CollectionsApiCall share the same NodePool.
@@ -79,7 +113,15 @@ class Client {
79113
Health(apiCall),
80114
Metrics(apiCall),
81115
Operations(apiCall),
82-
MultiSearch(apiCall));
116+
MultiSearch(apiCall),
117+
Stopwords(apiCall),
118+
CurationSets(apiCall),
119+
SynonymSets(apiCall),
120+
Stemming(apiCall),
121+
ConversationsModels(apiCall),
122+
NLSearchModels(apiCall),
123+
Conversations(apiCall),
124+
Analytics(apiCall));
83125
}
84126

85127
/// Perform operation on an individual collection having [collectionName].
@@ -113,4 +155,43 @@ class Client {
113155
}
114156
return _individualPresets[presetName]!;
115157
}
158+
159+
/// Perform operation on an individual stopwords set having [stopwordId].
160+
Stopword stopword(String stopwordId) {
161+
if (!_individualStopwords.containsKey(stopwordId)) {
162+
_individualStopwords[stopwordId] = Stopword(stopwordId, _apiCall);
163+
}
164+
return _individualStopwords[stopwordId]!;
165+
}
166+
167+
/// Perform operation on an individual curation set having [name].
168+
CurationSet curationSet(String name) {
169+
if (!_individualCurationSets.containsKey(name)) {
170+
_individualCurationSets[name] = CurationSet(name, _apiCall);
171+
}
172+
return _individualCurationSets[name]!;
173+
}
174+
175+
/// Perform operation on an individual synonym set having [name].
176+
SynonymSet synonymSet(String name) {
177+
if (!_individualSynonymSets.containsKey(name)) {
178+
_individualSynonymSets[name] = SynonymSet(name, _apiCall);
179+
}
180+
return _individualSynonymSets[name]!;
181+
}
182+
183+
ConversationModel conversationModel(String modelId) {
184+
return conversationsModels[modelId];
185+
}
186+
187+
NLSearchModel nlSearchModel(String modelId) {
188+
return nlSearchModels[modelId];
189+
}
190+
191+
Conversation conversation(String id) {
192+
if (!_individualConversations.containsKey(id)) {
193+
_individualConversations[id] = Conversation(id, _apiCall);
194+
}
195+
return _individualConversations[id]!;
196+
}
116197
}

lib/src/conversation.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import 'models/models.dart';
2+
import 'services/api_call.dart';
3+
import 'conversations.dart';
4+
5+
class Conversation {
6+
final String _id;
7+
final ApiCall _apiCall;
8+
9+
Conversation(String id, ApiCall apiCall)
10+
: _id = id,
11+
_apiCall = apiCall;
12+
13+
Future<List<ConversationSchema>> retrieve() async {
14+
final response = await _apiCall.getList(_endpointPath);
15+
return response
16+
.map((item) =>
17+
ConversationSchema.fromJson(Map<String, dynamic>.from(item)))
18+
.toList();
19+
}
20+
21+
Future<ConversationUpdateSchema> update(
22+
ConversationUpdateSchema params) async {
23+
final response =
24+
await _apiCall.put(_endpointPath, bodyParameters: params.toJson());
25+
return ConversationUpdateSchema.fromJson(response);
26+
}
27+
28+
Future<ConversationDeleteSchema> delete() async {
29+
final response = await _apiCall.delete(_endpointPath);
30+
return ConversationDeleteSchema.fromJson(response);
31+
}
32+
33+
String get _endpointPath =>
34+
'${Conversations.resourcepath}/${Uri.encodeComponent(_id)}';
35+
}

lib/src/conversation_model.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import 'models/models.dart';
2+
import 'services/api_call.dart';
3+
import 'conversations_models.dart';
4+
5+
class ConversationModel {
6+
final String _id;
7+
final ApiCall _apiCall;
8+
9+
ConversationModel(String id, ApiCall apiCall)
10+
: _id = id,
11+
_apiCall = apiCall;
12+
13+
Future<ConversationModelCreateSchema> update(
14+
ConversationModelCreateSchema params) async {
15+
final response =
16+
await _apiCall.put(_endpointPath, bodyParameters: params.toJson());
17+
return ConversationModelCreateSchema.fromJson(response);
18+
}
19+
20+
Future<ConversationModelSchema> retrieve() async {
21+
final response = await _apiCall.get(_endpointPath);
22+
return ConversationModelSchema.fromJson(response);
23+
}
24+
25+
Future<ConversationModelDeleteSchema> delete() async {
26+
final response = await _apiCall.delete(_endpointPath);
27+
return ConversationModelDeleteSchema.fromJson(response);
28+
}
29+
30+
String get _endpointPath =>
31+
'${ConversationsModels.resourcepath}/${Uri.encodeComponent(_id)}';
32+
}

0 commit comments

Comments
 (0)