Skip to content

Commit 06cdc51

Browse files
committed
docs(changeset): Add middleware support + add better docs for DB service.
1 parent 3c2c49a commit 06cdc51

File tree

26 files changed

+941
-530
lines changed

26 files changed

+941
-530
lines changed

.changeset/swift-facts-study.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@storybooker/azure-functions": minor
3+
"@storybooker/adapter-azure": minor
4+
"@storybooker/adapter-fs": minor
5+
"@storybooker/core": minor
6+
---
7+
8+
Add middleware support + add better docs for DB service.

packages/adapter-azure/src/blob-storage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from "node:path";
33
import { Readable } from "node:stream";
44
import type streamWeb from "node:stream/web";
55
import { BlobServiceClient, type BlobClient } from "@azure/storage-blob";
6-
import type { StorageService } from "@storybooker/core";
6+
import type { StorageService } from "@storybooker/core/types";
77

88
export class AzureBlobStorageService implements StorageService {
99
#client: BlobServiceClient;

packages/adapter-azure/src/cosmosdb.ts

Lines changed: 87 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { CosmosClient, type Database } from "@azure/cosmos";
2-
import {
3-
SERVICE_NAME,
4-
type DatabaseDocumentListOptions,
5-
type DatabaseService,
6-
} from "@storybooker/core";
2+
import { SERVICE_NAME } from "@storybooker/core/constants";
3+
import type {
4+
DatabaseDocumentListOptions,
5+
DatabaseService,
6+
DatabaseServiceOptions,
7+
StoryBookerDatabaseDocument,
8+
} from "@storybooker/core/types";
79

810
export class AzureCosmosDatabaseService implements DatabaseService {
911
#db: Database;
@@ -12,81 +14,113 @@ export class AzureCosmosDatabaseService implements DatabaseService {
1214
this.#db = new CosmosClient(connectionString).database(dbName);
1315
}
1416

15-
async init(): Promise<void> {
17+
init: DatabaseService["init"] = async () => {
1618
await this.#db.client.databases.createIfNotExists({ id: this.#db.id });
17-
}
19+
};
1820

19-
listCollections: DatabaseService["listCollections"] = async () => {
20-
const response = await this.#db.containers.readAll().fetchAll();
21+
listCollections: DatabaseService["listCollections"] = async (options) => {
22+
const response = await this.#db.containers
23+
.readAll({ abortSignal: options.abortSignal })
24+
.fetchAll();
2125
const collections: string[] = response.resources.map(
2226
(resource) => resource.id,
2327
);
2428

2529
return collections;
2630
};
2731

28-
createCollection: DatabaseService["createCollection"] = async (name) => {
29-
await this.#db.containers.create({ id: name });
32+
createCollection: DatabaseService["createCollection"] = async (
33+
collectionId,
34+
options,
35+
) => {
36+
await this.#db.containers.create(
37+
{ id: collectionId },
38+
{ abortSignal: options.abortSignal },
39+
);
3040
return;
3141
};
3242

33-
deleteCollection: DatabaseService["deleteCollection"] = async (name) => {
34-
await this.#db.container(name).delete();
43+
deleteCollection: DatabaseService["deleteCollection"] = async (
44+
collectionId,
45+
options,
46+
) => {
47+
await this.#db
48+
.container(collectionId)
49+
.delete({ abortSignal: options.abortSignal });
3550
return;
3651
};
3752

38-
listDocuments = async <Item extends { id: string }>(
39-
name: string,
40-
_options?: DatabaseDocumentListOptions<Item>,
41-
): Promise<Item[]> => {
42-
const items = await this.#db.container(name).items.readAll().fetchAll();
43-
return items.resources as Item[];
53+
listDocuments: DatabaseService["listDocuments"] = async <
54+
Document extends StoryBookerDatabaseDocument,
55+
>(
56+
collectionId: string,
57+
_listOptions: DatabaseDocumentListOptions<Document>,
58+
options: DatabaseServiceOptions,
59+
) => {
60+
const items = await this.#db
61+
.container(collectionId)
62+
.items.readAll({ abortSignal: options.abortSignal })
63+
.fetchAll();
64+
return items.resources as Document[];
4465
};
4566

46-
getDocument = async <Item extends { id: string }>(
47-
name: string,
48-
id: string,
49-
partitionKey = id,
50-
): Promise<Item> => {
51-
const item = this.#db.container(name).item(id, partitionKey);
52-
const response = await item.read();
53-
return { ...response.resource, id } as Item;
67+
getDocument: DatabaseService["getDocument"] = async <
68+
Document extends StoryBookerDatabaseDocument,
69+
>(
70+
collectionId: string,
71+
documentId: string,
72+
options: DatabaseServiceOptions,
73+
) => {
74+
const item = this.#db.container(collectionId).item(documentId);
75+
const response = await item.read({ abortSignal: options.abortSignal });
76+
const document: Document = response.resource;
77+
document.id = documentId;
78+
return document;
5479
};
5580

56-
createDocument = async <Item extends { id: string }>(
57-
name: string,
58-
item: Item,
59-
): Promise<void> => {
60-
await this.#db.container(name).items.create(item);
81+
createDocument: DatabaseService["createDocument"] = async (
82+
collectionId,
83+
documentData,
84+
options,
85+
) => {
86+
await this.#db
87+
.container(collectionId)
88+
.items.create(documentData, { abortSignal: options.abortSignal });
6189
return;
6290
};
6391

64-
deleteDocument = async (
65-
name: string,
66-
id: string,
67-
partitionKey = id,
68-
): Promise<void> => {
69-
await this.#db.container(name).item(id, partitionKey).delete();
92+
deleteDocument: DatabaseService["deleteDocument"] = async (
93+
collectionId,
94+
documentId,
95+
options,
96+
) => {
97+
await this.#db
98+
.container(collectionId)
99+
.item(documentId)
100+
.delete({ abortSignal: options.abortSignal });
70101
return;
71102
};
72103

73104
// oxlint-disable-next-line max-params
74-
updateDocument = async <Item extends { id: string }>(
75-
name: string,
76-
id: string,
77-
item: Partial<Omit<Item, "id">>,
78-
partitionKey = id,
79-
): Promise<void> => {
105+
updateDocument: DatabaseService["updateDocument"] = async (
106+
collectionId,
107+
documentId,
108+
documentData,
109+
options,
110+
) => {
80111
await this.#db
81-
.container(name)
82-
.item(id, partitionKey)
83-
.patch<Item>({
84-
operations: Object.entries(item).map(([key, value]) => ({
85-
op: "replace",
86-
path: `/${key}`,
87-
value,
88-
})),
89-
});
112+
.container(collectionId)
113+
.item(documentId)
114+
.patch<Document>(
115+
{
116+
operations: Object.entries(documentData).map(([key, value]) => ({
117+
op: "replace",
118+
path: `/${key}`,
119+
value,
120+
})),
121+
},
122+
{ abortSignal: options.abortSignal },
123+
);
90124

91125
return;
92126
};

packages/adapter-azure/src/data-tables.ts

Lines changed: 74 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import {
66
import type {
77
DatabaseDocumentListOptions,
88
DatabaseService,
9-
} from "@storybooker/core";
9+
DatabaseServiceOptions,
10+
StoryBookerDatabaseDocument,
11+
} from "@storybooker/core/types";
1012

1113
export class AzureDataTablesDatabaseService implements DatabaseService {
1214
#connectionString: string;
@@ -18,9 +20,11 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
1820
TableServiceClient.fromConnectionString(connectionString);
1921
}
2022

21-
listCollections: DatabaseService["listCollections"] = async () => {
23+
listCollections: DatabaseService["listCollections"] = async (options) => {
2224
const collections: string[] = [];
23-
for await (const table of this.#serviceClient.listTables()) {
25+
for await (const table of this.#serviceClient.listTables({
26+
abortSignal: options.abortSignal,
27+
})) {
2428
if (table.name) {
2529
collections.push(table.name);
2630
}
@@ -29,38 +33,52 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
2933
return collections;
3034
};
3135

32-
createCollection: DatabaseService["createCollection"] = async (name) => {
33-
await this.#serviceClient.createTable(name);
36+
createCollection: DatabaseService["createCollection"] = async (
37+
collectionId,
38+
options,
39+
) => {
40+
await this.#serviceClient.createTable(collectionId, {
41+
abortSignal: options.abortSignal,
42+
});
3443
return;
3544
};
3645

37-
deleteCollection: DatabaseService["deleteCollection"] = async (name) => {
38-
await this.#serviceClient.deleteTable(name);
46+
deleteCollection: DatabaseService["deleteCollection"] = async (
47+
collectionId,
48+
options,
49+
) => {
50+
await this.#serviceClient.deleteTable(collectionId, {
51+
abortSignal: options.abortSignal,
52+
});
3953
return;
4054
};
4155

42-
listDocuments = async <Item extends { id: string }>(
43-
tableName: string,
44-
options?: DatabaseDocumentListOptions<Item>,
45-
): Promise<Item[]> => {
46-
const { filter, limit, select, sort } = options || {};
56+
listDocuments: DatabaseService["listDocuments"] = async <
57+
Document extends StoryBookerDatabaseDocument,
58+
>(
59+
collectionId: string,
60+
listOptions: DatabaseDocumentListOptions<Document>,
61+
options: DatabaseServiceOptions,
62+
): Promise<Document[]> => {
63+
const { filter, limit, select, sort } = listOptions || {};
4764
const tableClient = TableClient.fromConnectionString(
4865
this.#connectionString,
49-
tableName,
66+
collectionId,
5067
);
5168
const pageIterator = tableClient
5269
.listEntities({
70+
abortSignal: options.abortSignal,
5371
queryOptions: {
5472
filter: typeof filter === "string" ? filter : undefined,
5573
select,
5674
},
5775
})
5876
.byPage({ maxPageSize: limit });
5977

60-
const items: Item[] = [];
78+
const items: Document[] = [];
6179
for await (const page of pageIterator) {
6280
for (const entity of page) {
63-
const item = this.#entityToItem<Item>(entity);
81+
const item = this.#entityToItem<Document>(entity);
6482
if (filter && typeof filter === "function") {
6583
if (filter(item)) {
6684
items.push(item);
@@ -80,65 +98,76 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
8098
return items;
8199
};
82100

83-
getDocument = async <Item extends { id: string }>(
84-
tableName: string,
85-
id: string,
86-
partitionKey = id,
87-
): Promise<Item> => {
101+
getDocument: DatabaseService["getDocument"] = async <
102+
Document extends StoryBookerDatabaseDocument,
103+
>(
104+
collectionId: string,
105+
documentId: string,
106+
options: DatabaseServiceOptions,
107+
): Promise<Document> => {
88108
const tableClient = TableClient.fromConnectionString(
89109
this.#connectionString,
90-
tableName,
110+
collectionId,
91111
);
92-
const entity = await tableClient.getEntity(partitionKey, id);
112+
const entity = await tableClient.getEntity(collectionId, documentId, {
113+
abortSignal: options.abortSignal,
114+
});
93115

94-
return this.#entityToItem<Item>(entity);
116+
return this.#entityToItem<Document>(entity);
95117
};
96118

97-
createDocument = async <Item extends { id: string }>(
98-
tableName: string,
99-
item: Item,
119+
createDocument: DatabaseService["createDocument"] = async (
120+
collectionId,
121+
documentData,
122+
options,
100123
): Promise<void> => {
101124
const tableClient = TableClient.fromConnectionString(
102125
this.#connectionString,
103-
tableName,
126+
collectionId,
127+
);
128+
await tableClient.createEntity(
129+
{
130+
...documentData,
131+
partitionKey: collectionId,
132+
rowKey: documentData.id,
133+
},
134+
{ abortSignal: options.abortSignal },
104135
);
105-
await tableClient.createEntity({
106-
...item,
107-
partitionKey: item.id,
108-
rowKey: item.id,
109-
});
110136

111137
return;
112138
};
113139

114-
deleteDocument = async (
115-
tableName: string,
116-
id: string,
117-
partitionKey = id,
140+
deleteDocument: DatabaseService["deleteDocument"] = async (
141+
collectionId,
142+
documentId,
143+
options,
118144
): Promise<void> => {
119145
const tableClient = TableClient.fromConnectionString(
120146
this.#connectionString,
121-
tableName,
147+
collectionId,
122148
);
123-
await tableClient.deleteEntity(partitionKey, id);
149+
await tableClient.deleteEntity(collectionId, documentId, {
150+
abortSignal: options.abortSignal,
151+
});
124152

125153
return;
126154
};
127155

128156
// oxlint-disable-next-line max-params
129-
updateDocument = async <Item extends { id: string }>(
130-
tableName: string,
131-
id: string,
132-
item: Partial<Omit<Item, "id">>,
133-
partitionKey = id,
157+
updateDocument: DatabaseService["updateDocument"] = async (
158+
collectionId,
159+
documentId,
160+
documentData,
161+
options,
134162
): Promise<void> => {
135163
const tableClient = TableClient.fromConnectionString(
136164
this.#connectionString,
137-
tableName,
165+
collectionId,
138166
);
139167
await tableClient.updateEntity(
140-
{ ...item, partitionKey, rowKey: id },
168+
{ ...documentData, partitionKey: collectionId, rowKey: documentId },
141169
"Merge",
170+
{ abortSignal: options.abortSignal },
142171
);
143172

144173
return;

0 commit comments

Comments
 (0)