Skip to content

Commit 2db1858

Browse files
committed
docs(changeset): Fix missing routes and normalise collection/container names in adapter
1 parent 5927ec8 commit 2db1858

File tree

20 files changed

+181
-117
lines changed

20 files changed

+181
-117
lines changed

.changeset/busy-sloths-brake.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@storybooker/adapter-azure": minor
3+
"@storybooker/core": minor
4+
"@storybooker/adapter-fs": minor
5+
"@storybooker/azure-functions": minor
6+
---
7+
8+
Fix missing routes and normalise collection/container names in adapter

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export class AzureBlobStorageService implements StorageService {
1818
containerId,
1919
options,
2020
) => {
21-
await this.#client.createContainer(containerId, {
21+
const containerName = genContainerNameFromContainerId(containerId);
22+
await this.#client.createContainer(containerName, {
2223
abortSignal: options.abortSignal,
2324
});
2425
};
@@ -27,7 +28,8 @@ export class AzureBlobStorageService implements StorageService {
2728
containerId,
2829
options,
2930
) => {
30-
await this.#client.getContainerClient(containerId).deleteIfExists({
31+
const containerName = genContainerNameFromContainerId(containerId);
32+
await this.#client.getContainerClient(containerName).deleteIfExists({
3133
abortSignal: options.abortSignal,
3234
});
3335
};
@@ -36,7 +38,8 @@ export class AzureBlobStorageService implements StorageService {
3638
containerId,
3739
options,
3840
) => {
39-
return await this.#client.getContainerClient(containerId).exists({
41+
const containerName = genContainerNameFromContainerId(containerId);
42+
return await this.#client.getContainerClient(containerName).exists({
4043
abortSignal: options.abortSignal,
4144
});
4245
};
@@ -57,7 +60,8 @@ export class AzureBlobStorageService implements StorageService {
5760
filePathsOrPrefix,
5861
options,
5962
) => {
60-
const containerClient = this.#client.getContainerClient(containerId);
63+
const containerName = genContainerNameFromContainerId(containerId);
64+
const containerClient = this.#client.getContainerClient(containerName);
6165
const blobClientsToDelete: BlobClient[] = [];
6266

6367
if (typeof filePathsOrPrefix === "string") {
@@ -94,7 +98,8 @@ export class AzureBlobStorageService implements StorageService {
9498
files,
9599
options,
96100
) => {
97-
const containerClient = this.#client.getContainerClient(containerId);
101+
const containerName = genContainerNameFromContainerId(containerId);
102+
const containerClient = this.#client.getContainerClient(containerName);
98103
// oxlint-disable-next-line require-await
99104
const promises = files.map(async ({ content, path, mimeType }) =>
100105
this.#uploadFile(
@@ -149,7 +154,8 @@ export class AzureBlobStorageService implements StorageService {
149154
filepath,
150155
options,
151156
) => {
152-
const containerClient = this.#client.getContainerClient(containerId);
157+
const containerName = genContainerNameFromContainerId(containerId);
158+
const containerClient = this.#client.getContainerClient(containerName);
153159
const blockBlobClient = containerClient.getBlockBlobClient(filepath);
154160
return await blockBlobClient.exists({ abortSignal: options.abortSignal });
155161
};
@@ -159,7 +165,8 @@ export class AzureBlobStorageService implements StorageService {
159165
filepath,
160166
options,
161167
) => {
162-
const containerClient = this.#client.getContainerClient(containerId);
168+
const containerName = genContainerNameFromContainerId(containerId);
169+
const containerClient = this.#client.getContainerClient(containerName);
163170
const blockBlobClient = containerClient.getBlockBlobClient(filepath);
164171

165172
if (!(await blockBlobClient.exists())) {
@@ -185,3 +192,10 @@ export class AzureBlobStorageService implements StorageService {
185192
};
186193
};
187194
}
195+
196+
function genContainerNameFromContainerId(containerId: string): string {
197+
return containerId
198+
.replaceAll(/[^\w-]+/g, "-")
199+
.slice(0, 255)
200+
.toLowerCase();
201+
}

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

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
3838
collectionId,
3939
options,
4040
) => {
41-
await this.#serviceClient.createTable(collectionId, {
41+
const tableName = genTableNameFromCollectionId(collectionId);
42+
await this.#serviceClient.createTable(tableName, {
4243
abortSignal: options.abortSignal,
4344
});
4445
return;
@@ -49,9 +50,10 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
4950
options,
5051
) => {
5152
try {
53+
const tableName = genTableNameFromCollectionId(collectionId);
5254
const iterator = this.#serviceClient.listTables({
5355
abortSignal: options.abortSignal,
54-
queryOptions: { filter: odata`TableName eq ${collectionId}` },
56+
queryOptions: { filter: odata`TableName eq ${tableName}` },
5557
});
5658
for await (const table of iterator) {
5759
if (table.name === collectionId) {
@@ -69,7 +71,8 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
6971
collectionId,
7072
options,
7173
) => {
72-
await this.#serviceClient.deleteTable(collectionId, {
74+
const tableName = genTableNameFromCollectionId(collectionId);
75+
await this.#serviceClient.deleteTable(tableName, {
7376
abortSignal: options.abortSignal,
7477
});
7578
return;
@@ -83,9 +86,11 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
8386
options: DatabaseServiceOptions,
8487
): Promise<Document[]> => {
8588
const { filter, limit, select, sort } = listOptions || {};
89+
90+
const tableName = genTableNameFromCollectionId(collectionId);
8691
const tableClient = TableClient.fromConnectionString(
8792
this.#connectionString,
88-
collectionId,
93+
tableName,
8994
);
9095
const pageIterator = tableClient
9196
.listEntities({
@@ -127,9 +132,10 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
127132
documentId: string,
128133
options: DatabaseServiceOptions,
129134
): Promise<Document> => {
135+
const tableName = genTableNameFromCollectionId(collectionId);
130136
const tableClient = TableClient.fromConnectionString(
131137
this.#connectionString,
132-
collectionId,
138+
tableName,
133139
);
134140
const entity = await tableClient.getEntity(collectionId, documentId, {
135141
abortSignal: options.abortSignal,
@@ -155,9 +161,10 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
155161
documentData,
156162
options,
157163
) => {
164+
const tableName = genTableNameFromCollectionId(collectionId);
158165
const tableClient = TableClient.fromConnectionString(
159166
this.#connectionString,
160-
collectionId,
167+
tableName,
161168
);
162169
await tableClient.createEntity(
163170
{
@@ -176,9 +183,10 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
176183
documentId,
177184
options,
178185
) => {
186+
const tableName = genTableNameFromCollectionId(collectionId);
179187
const tableClient = TableClient.fromConnectionString(
180188
this.#connectionString,
181-
collectionId,
189+
tableName,
182190
);
183191
await tableClient.deleteEntity(collectionId, documentId, {
184192
abortSignal: options.abortSignal,
@@ -194,9 +202,10 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
194202
documentData,
195203
options,
196204
) => {
205+
const tableName = genTableNameFromCollectionId(collectionId);
197206
const tableClient = TableClient.fromConnectionString(
198207
this.#connectionString,
199-
collectionId,
208+
tableName,
200209
);
201210
await tableClient.updateEntity(
202211
{ ...documentData, partitionKey: collectionId, rowKey: documentId },
@@ -216,3 +225,11 @@ export class AzureDataTablesDatabaseService implements DatabaseService {
216225
} as unknown as Item;
217226
};
218227
}
228+
229+
function genTableNameFromCollectionId(collectionId: string): string {
230+
if (/^[A-Za-z][A-Za-z0-9]{2,62}$/.test(collectionId)) {
231+
return collectionId;
232+
}
233+
234+
return collectionId.replaceAll(/\W/g, "").slice(0, 63).padEnd(3, "X");
235+
}

packages/core/package.json

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,6 @@
7575
"import": "./dist/constants.js",
7676
"require": "./dist/constants.cjs"
7777
},
78-
"./router": {
79-
"source": "./src/router.ts",
80-
"import": "./dist/router.js",
81-
"require": "./dist/router.cjs"
82-
},
8378
"./translations": {
8479
"source": "./src/translations/index.ts",
8580
"import": "./dist/translations.js",
@@ -113,10 +108,6 @@
113108
"import": "./dist/constants.js",
114109
"require": "./dist/constants.cjs"
115110
},
116-
"./router": {
117-
"import": "./dist/router.js",
118-
"require": "./dist/router.cjs"
119-
},
120111
"./translations": {
121112
"import": "./dist/translations.js",
122113
"require": "./dist/translations.cjs"

packages/core/src/builds/model.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import { getStore } from "#store";
1212
import { writeStreamToFile } from "#utils/file-utils";
1313
import { getMimeType } from "#utils/mime-utils";
1414
import {
15-
generateProjectCollectionName,
16-
generateProjectContainerName,
15+
generateDatabaseCollectionId,
16+
generateStorageContainerId,
1717
Model,
1818
type BaseModel,
1919
type ListOptions,
@@ -30,7 +30,7 @@ import {
3030

3131
export class BuildsModel extends Model<BuildType> {
3232
constructor(projectId: string) {
33-
super(projectId, generateProjectCollectionName(projectId, "Builds"));
33+
super(projectId, generateDatabaseCollectionId(projectId, "Builds"));
3434
}
3535

3636
async list(options: ListOptions<BuildType> = {}): Promise<BuildType[]> {
@@ -41,7 +41,7 @@ export class BuildsModel extends Model<BuildType> {
4141
}
4242

4343
const items = await this.database.listDocuments(
44-
this.collectionName,
44+
this.collectionId,
4545
options,
4646
this.dbOptions,
4747
);
@@ -81,7 +81,7 @@ export class BuildsModel extends Model<BuildType> {
8181
updatedAt: now,
8282
};
8383
await this.database.createDocument<BuildType>(
84-
this.collectionName,
84+
this.collectionId,
8585
build,
8686
this.dbOptions,
8787
);
@@ -103,7 +103,7 @@ export class BuildsModel extends Model<BuildType> {
103103
this.log("Get build '%s'...", id);
104104

105105
const item = await this.database.getDocument(
106-
this.collectionName,
106+
this.collectionId,
107107
id,
108108
this.dbOptions,
109109
);
@@ -115,7 +115,7 @@ export class BuildsModel extends Model<BuildType> {
115115
this.log("Check build '%s'...", id);
116116

117117
return await this.database.hasDocument(
118-
this.collectionName,
118+
this.collectionId,
119119
id,
120120
this.dbOptions,
121121
);
@@ -125,7 +125,7 @@ export class BuildsModel extends Model<BuildType> {
125125
this.log("Update build '%s''...", id);
126126
const parsedData = BuildUpdateSchema.parse(data);
127127
await this.database.updateDocument(
128-
this.collectionName,
128+
this.collectionId,
129129
id,
130130
{ ...parsedData, updatedAt: new Date().toISOString() },
131131
this.dbOptions,
@@ -141,15 +141,15 @@ export class BuildsModel extends Model<BuildType> {
141141

142142
this.debug("Delete document '%s'", buildId);
143143
await this.database.deleteDocument(
144-
this.collectionName,
144+
this.collectionId,
145145
buildId,
146146
this.dbOptions,
147147
);
148148

149149
try {
150150
this.debug("Delete files '%s'", buildId);
151151
await this.storage.deleteFiles(
152-
generateProjectContainerName(this.projectId),
152+
generateStorageContainerId(this.projectId),
153153
buildId,
154154
this.storageOptions,
155155
);
@@ -325,7 +325,7 @@ export class BuildsModel extends Model<BuildType> {
325325

326326
this.debug("(%s-%s) Upload uncompressed dir", buildSHA, variant);
327327
await this.storage.uploadFiles(
328-
generateProjectContainerName(this.projectId),
328+
generateStorageContainerId(this.projectId),
329329
await this.#dirToFiles(dirpath, buildSHA),
330330
this.storageOptions,
331331
);

packages/core/src/handlers/handle-purge.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ async function purgeProject(project: ProjectType): Promise<void> {
3535
Date.now() - purgeBuildsAfterDays * ONE_DAY_IN_MS,
3636
);
3737
logger.log(
38-
`[Project: ${projectId}] Purge builds which were last modified more than ${purgeBuildsAfterDays} days ago - since ${new Date(
38+
`[Project: ${projectId}] Purge builds which were last modified more than ${purgeBuildsAfterDays} days ago - before ${new Date(
3939
expiryTime,
4040
).toLocaleString(locale)}`,
4141
);

packages/core/src/handlers/handle-serve-storybook.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { urlBuilder } from "#urls";
55
import { authenticateOrThrow } from "#utils/auth";
66
import { getMimeType } from "#utils/mime-utils";
77
import { responseError } from "#utils/response";
8-
import { generateProjectContainerName } from "#utils/shared-model";
8+
import { generateStorageContainerId } from "#utils/shared-model";
99

1010
export async function handleServeStoryBook({
1111
buildSHA,
@@ -22,7 +22,7 @@ export async function handleServeStoryBook({
2222

2323
try {
2424
const { content, mimeType } = await storage.downloadFile(
25-
generateProjectContainerName(projectId),
25+
generateStorageContainerId(projectId),
2626
storageFilepath,
2727
{ abortSignal },
2828
);

packages/core/src/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
// oxlint-disable max-lines-per-function
22

3+
import * as buildsRoutes from "#builds/routes";
34
import { DEFAULT_LOCALE, HEADERS } from "#constants";
5+
import * as labelsRoutes from "#labels/routes";
6+
import * as projectsRoutes from "#projects/routes";
7+
import { router } from "#router";
48
import { localStore } from "#store";
59
import { parseErrorMessage } from "#utils/error";
610
import { createMiddlewaresPipelineRequestHandler } from "#utils/middleware-utils";
11+
import * as accountRoutes from "./account/routes";
712
import { handlePurge, type HandlePurge } from "./handlers/handle-purge";
813
import { handleStaticFileRoute } from "./handlers/handle-static-file-route";
9-
import { router } from "./router";
14+
import * as rootRoutes from "./root/routes";
1015
import { translations_enGB } from "./translations/en-gb";
1116
import type {
1217
AuthService,
@@ -16,6 +21,14 @@ import type {
1621
StoryBookerUser,
1722
} from "./types";
1823

24+
router.registerGroup(rootRoutes);
25+
router.registerGroup(projectsRoutes);
26+
router.registerGroup(labelsRoutes);
27+
router.registerGroup(buildsRoutes);
28+
router.registerGroup(accountRoutes);
29+
30+
export { router };
31+
1932
export type {
2033
OpenAPIOptions,
2134
RequestHandler,

0 commit comments

Comments
 (0)