Skip to content

Commit 0d93356

Browse files
authored
Merge pull request #48 from haydenhoang/v2
Typesense Swift v2
2 parents 8057f2c + 2aa3815 commit 0d93356

193 files changed

Lines changed: 11710 additions & 2343 deletions

File tree

Some content is hidden

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

.github/workflows/tests.yml

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,28 @@ concurrency:
1616

1717
jobs:
1818
test:
19-
runs-on: macos-latest
19+
runs-on: macos-15-intel
2020
steps:
2121
- uses: actions/checkout@v4
22-
- name: Install and start dependencies
23-
run: |
24-
brew install docker
25-
brew install qemu
26-
brew install colima
27-
# https://github.com/abiosoft/colima/issues/424#issuecomment-1335912905
28-
colima delete
29-
colima start --arch x86_64
22+
- name: Setup Docker on macOS
23+
id: setup-docker
24+
uses: douglascamata/setup-docker-macos-action@v1.0.2
25+
with:
26+
lima: v1.2.1
27+
colima: v0.9.1
28+
colima-network-address: false
3029

3130
- name: Run Typesense
3231
run: |
3332
mkdir $(pwd)/typesense-data
3433
docker run -p 8108:8108 \
3534
-d \
36-
-v$(pwd)/typesense-data:/data typesense/typesense:28.0 \
35+
-v$(pwd)/typesense-data:/data typesense/typesense:30.0.rca34 \
3736
--data-dir /data \
3837
--api-key=xyz \
39-
--enable-cors
38+
--enable-cors \
39+
--enable-search-analytics=true \
40+
--analytics-dir=/analytics-data
4041
shell: bash
4142

4243
- name: Set up Xcode

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@
55
xcuserdata/
66
DerivedData/
77
.swiftpm
8+
9+
/typesense-data
10+
11+
openapi.yml

Package.resolved

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ let package = Package(
2121
url: "https://github.com/Flight-School/AnyCodable",
2222
from: "0.6.0"
2323
),
24+
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.0"),
25+
.package(url: "https://github.com/jpsim/Yams.git", from: "5.0.0")
2426
],
2527
targets: [
2628
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@@ -31,5 +33,14 @@ let package = Package(
3133
.testTarget(
3234
name: "TypesenseTests",
3335
dependencies: ["Typesense"]),
36+
37+
.executableTarget(
38+
name: "Tasks",
39+
dependencies: [
40+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
41+
.product(name: "Yams", package: "Yams")
42+
],
43+
path: "Tasks"
44+
)
3445
]
3546
)

README.md

Lines changed: 115 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,12 @@ This returns a `SearchResult` object as the data, which can be further parsed as
9191
```swift
9292
let jsonL = Data("{}".utf8)
9393
let (data, response) = try await client.collection(name: "companies").documents().importBatch(jsonL, options: ImportDocumentsParameters(
94-
action: .upsert,
95-
batchSize: 10,
96-
dirtyValues: .drop,
97-
remoteEmbeddingBatchSize: 10,
98-
returnDoc: true,
99-
returnId: false
94+
batchSize: 10,
95+
returnId: false,
96+
remoteEmbeddingBatchSize: 10,
97+
returnDoc: true,
98+
action: .upsert,
99+
dirtyValues: .drop
100100
))
101101
```
102102

@@ -105,7 +105,7 @@ let (data, response) = try await client.collection(name: "companies").documents(
105105
```swift
106106
let (data, response) = try await client.collection(name: "companies").documents().update(
107107
document: ["company_size": "large"],
108-
options: UpdateDocumentsByFilterParameters(filterBy: "num_employees:>1000")
108+
options: UpdateDocumentsParameters(filterBy: "num_employees:>1000")
109109
)
110110
```
111111

@@ -151,7 +151,7 @@ let (data, response) = try await client.aliases().delete(name: "companies")
151151
### Create an API key
152152

153153
```swift
154-
let adminKey = ApiKeySchema(_description: "Test key with all privileges", actions: ["*"], collections: ["*"])
154+
let adminKey = ApiKeySchema(description: "Test key with all privileges", actions: ["*"], collections: ["*"])
155155
let (data, response) = try await client.keys().create(adminKey)
156156
```
157157

@@ -177,13 +177,13 @@ let (data, response) = try await client.keys().delete(id: 1)
177177

178178
```swift
179179
let schema = ConversationModelCreateSchema(
180-
_id: "conv-model-1",
181180
modelName: "openai/gpt-3.5-turbo",
182-
apiKey: "OPENAI_API_KEY",
183181
historyCollection: "conversation_store",
182+
maxBytes: 16384,
183+
id: "conv-model-1",
184+
apiKey: "OPENAI_API_KEY",
184185
systemPrompt: "You are an assistant for question-answering...",
185186
ttl: 10000,
186-
maxBytes: 16384
187187
)
188188
let (data, response) = try await client.conversations().models().create(params: schema)
189189
```
@@ -214,50 +214,76 @@ let (data, response) = try await client.conversations().model(modelId: "conv-mod
214214
let (data, response) = try await client.conversations().model(modelId: "conv-model-1").delete()
215215
```
216216

217-
### Create or update an override
217+
### Create or update a curation set
218218

219219
```swift
220-
let schema = SearchOverrideSchema<MetadataType>(
221-
rule: SearchOverrideRule(tags: ["test"], query: "apple", match: SearchOverrideRule.Match.exact, filterBy: "employees:=50"),
222-
includes: [SearchOverrideInclude(_id: "include-id", position: 1)],
223-
excludes: [SearchOverrideExclude(_id: "exclude-id")],
224-
filterBy: "test:=true",
225-
removeMatchedTokens: false,
226-
metadata: MetadataType(message: "test-json"),
227-
sortBy: "num_employees:desc",
228-
replaceQuery: "test",
229-
filterCuratedHits: false,
230-
effectiveFromTs: 123,
231-
effectiveToTs: 456,
232-
stopProcessing: false
233-
)
234-
let (data, response) = try await client.collection(name: "books").overrides().upsert(overrideId: "test-id", params: schema)
220+
let schema = CurationSetCreateSchema(items: [
221+
CurationItemCreateSchema(
222+
rule: CurationRule( query: "apple", match: .exact),
223+
includes: [
224+
CurationInclude(id: "422", position: 1),
225+
CurationInclude(id: "54", position: 2),
226+
], excludes: [CurationExclude(id: "287")],
227+
id: "customize-apple"
228+
)
229+
])
230+
let (data, response) = try await client.curationSets().upsert("curate_products", schema)
235231
```
236232

237-
### Retrieve all overrides
233+
### Retrieve all curation sets
238234

239235
```swift
240-
let (data, response) = try await client.collection(name: "books").overrides().retrieve(metadataType: Never.self)
236+
let (data, response) = try await client.curationSets().retrieve()
241237
```
242238

243-
### Retrieve an override
239+
### Retrieve a curation set
244240

245241
```swift
246-
let (data, response) = try await client.collection(name: "books").override("test-id").retrieve(metadataType: MetadataType.self)
242+
let (data, response) = try await client.curationSet("curate_products").retrieve()
247243
```
248244

249-
### Delete an override
245+
### Delete a curation set
250246

251247
```swift
252-
let (data, response) = try await client.collection(name: "books").override("test-id").delete()
248+
let (data, response) = try await client.curationSet("curate_products").delete()
249+
```
250+
251+
### Retrieve all curation set items
252+
253+
```swift
254+
let (data, response) = try await client.curationSet("curate_products").items().retrieve()
255+
```
256+
257+
### Upsert a curation set item
258+
259+
```swift
260+
let (data, response) = try await client.curationSet("curate_products").items().upsert("customize-apple-2", CurationItemCreateSchema(
261+
rule: CurationRule( query: "apple", match: .exact),
262+
includes: [
263+
CurationInclude(id: "422", position: 1),
264+
CurationInclude(id: "54", position: 2),
265+
], excludes: [CurationExclude(id: "287")],
266+
))
267+
```
268+
269+
### Retrieve a curation set item
270+
271+
```swift
272+
let (data, response) = try await client.curationSet("curate_products").item("customize-apple").retrieve()
273+
```
274+
275+
### Delete a curation set item
276+
277+
```swift
278+
let (data, response) = try await client.curationSet("curate_products").item("customize-apple").delete()
253279
```
254280

255281
### Create or update a preset
256282

257283
```swift
258284
let schema = PresetUpsertSchema(
259-
value: PresetValue.singleCollectionSearch(SearchParameters(q: "apple"))
260-
// or: value: PresetValue.multiSearch(MultiSearchSearchesParameter(searches: [MultiSearchCollectionParameters(q: "apple")]))
285+
value: PresetUpsertSchemaValue.typeSearchParameters(SearchParameters(q: "apple"))
286+
// or: value: PresetUpsertSchemaValue.typeMultiSearchSearchesParameter(MultiSearchSearchesParameter(searches: [MultiSearchCollectionParameters(q: "apple")]))
261287
)
262288
let (data, response) = try await client.presets().upsert(presetName: "listing_view", params: schema)
263289
```
@@ -274,9 +300,9 @@ let (data, response) = try await client.presets().retrieve()
274300
let (data, response) = try await client.preset("listing_view").retrieve()
275301

276302
switch data?.value {
277-
case .singleCollectionSearch(let value):
303+
case .typeSearchParameters(let value):
278304
print(value)
279-
case .multiSearch(let value):
305+
case .typeMultiSearchSearchesParameter(let value):
280306
print(value)
281307
}
282308
```
@@ -318,26 +344,53 @@ let (data, response) = try await client.stopword("stopword_set1").delete()
318344
### Create or update a synonym
319345

320346
```swift
321-
let schema = SearchSynonymSchema(synonyms: ["blazer", "coat", "jacket"])
322-
let (data, response) = try await client.collection(name: "products").synonyms().upsert(id: "coat-synonyms", schema)
347+
let schema = SynonymSetCreateSchema(items: [
348+
SynonymItemSchema(synonyms: ["blazer", "coat", "jacket"], id:"coat-synonyms", root: "outerwear")
349+
])
350+
let (data, response) = try await utilClient.synonymSets().upsert("clothing-synonyms", schema)
323351
```
324352

325353
### Retrieve all synonyms
326354

327355
```swift
328-
let (data, response) = try await client.collection(name: "products").synonyms().retrieve()
356+
let (data, response) = try await client.synonymSets().retrieve()
329357
```
330358

331359
### Retrieve a synonym
332360

333361
```swift
334-
let (data, response) = try await client.collection(name: "products").synonyms().retrieve(id: "coat-synonyms")
362+
let (data, response) = try await client.synonymSet("clothing-synonyms").retrieve()
335363
```
336364

337365
### Delete a synonym
338366

339367
```swift
340-
let (data, response) = try await myClient.collection(name: "products").synonyms().delete(id: "coat-synonyms")
368+
let (data, response) = try await client.synonymSet("clothing-synonyms").delete()
369+
```
370+
371+
### Upsert a synonym item
372+
373+
```swift
374+
let schema = SynonymItemUpsertSchema(synonyms: ["blazer", "coat", "jacket"], root: "outerwear")
375+
let (data, response) = try await client.synonymSet("clothing-synonyms").items().upsert("coat-synonyms", schema)
376+
```
377+
378+
### Retrieve all synonym items
379+
380+
```swift
381+
let (data, response) = try await client.synonymSet("clothing-synonyms").items().retrieve()
382+
```
383+
384+
### Retrieve a synonym item
385+
386+
```swift
387+
let (data, response) = try await client.synonymSet("clothing-synonyms").item("coat-synonyms").retrieve()
388+
```
389+
390+
### Delete a synonym item
391+
392+
```swift
393+
let (data, response) = try await client.synonymSet("clothing-synonyms").item("coat-synonyms").delete()
341394
```
342395

343396
### Retrieve debug information
@@ -390,13 +443,29 @@ let (data, response) = try await client.operations().snapshot(path: "/tmp/typese
390443

391444
## Contributing
392445

393-
Issues and pull requests are welcome on GitHub at [Typesense Swift](https://github.com/typesense/typesense-swift). Do note that the Models used in the Swift client are generated by [Swagger-Codegen](https://github.com/swagger-api/swagger-codegen) and are automated to be modified in order to prevent major errors. So please do use the shell script that is provided in the repo to generate the models:
446+
Issues and pull requests are welcome on GitHub at [Typesense Swift](https://github.com/typesense/typesense-swift). Do note that the Models used in the Swift client are generated by [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator).
394447

395-
```shell
396-
sh get-models.sh
448+
When updating or adding new parameters and endpoints, make changes directly in the [Typesense API spec repository](https://github.com/typesense/typesense-api-spec).
449+
450+
Once your changes are merged, you can update this project as follows:
451+
452+
```bash
453+
swift run Tasks fetch
454+
swift run Tasks preprocess
455+
swift run Tasks code-gen
397456
```
398457

399-
The generated Models (inside the Models directory) are to be used inside the Models directory of the source code as well. Models need to be generated as and when the [Typesense-Api-Spec](https://github.com/typesense/typesense-api-spec) is updated.
458+
This will:
459+
460+
- Download the latest API spec.
461+
- Write it to our local `openapi.yml`.
462+
- Preprocess it into [`preprocessed_openapi.yml`](./preprocessed_openapi.yml).
463+
- Generate and replace the `Sources/Typesense/Models` folder.
464+
465+
The preprocessing step does two things:
466+
467+
- Flatten the URL params defined as objects into individual URL parameters (in [`PreprocessOpenAPI.swift`](Tasks/PreprocessOpenAPI.swift))
468+
- Inject OpenAPI vendor attributes `x-swift-*` (e.g., generic parameters, schema builders) into the spec before code generation (in [`AddVendorAttributes.swift`](Tasks/AddVendorAttributes.swift))
400469

401470
## TODO: Features
402471

Sources/Typesense/Analytics.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Foundation
22

33
public struct Analytics {
4-
static let resourcePath: String = "/analytics"
4+
static let resourcePath: String = "analytics"
55

66
private var analyticsRules: AnalyticsRules
77
var apiCall: ApiCall
@@ -11,12 +11,12 @@ public struct Analytics {
1111
self.analyticsRules = AnalyticsRules(apiCall: apiCall)
1212
}
1313

14-
public func events() -> AnalyticsEvents {
15-
return AnalyticsEvents(apiCall: self.apiCall)
14+
public func events() -> AnalyticsEventsAPI {
15+
return AnalyticsEventsAPI(apiCall: self.apiCall)
1616
}
1717

18-
public func rule(id: String) -> AnalyticsRule {
19-
return AnalyticsRule(name: id, apiCall: self.apiCall)
18+
public func rule(_ name: String) -> AnalyticsRuleAPI {
19+
return AnalyticsRuleAPI(name: name, apiCall: self.apiCall)
2020
}
2121

2222
public func rules() -> AnalyticsRules {

0 commit comments

Comments
 (0)