Skip to content

Commit a7b24df

Browse files
ENGG-3158: collection description support in local sync (#136)
1 parent 6fb1cda commit a7b24df

File tree

6 files changed

+153
-36
lines changed

6 files changed

+153
-36
lines changed

src/renderer/actions/local-sync/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { homedir } from "os";
22

3-
43
export const CONFIG_FILE = "requestly.json";
4+
export const DESCRIPTION_FILE = "README.md";
55
export const COLLECTION_VARIABLES_FILE = "vars.json";
66
export const ENVIRONMENT_VARIABLES_FILE = "env.json";
77
export const ENVIRONMENT_VARIABLES_FOLDER = "environments";

src/renderer/actions/local-sync/fs-manager.rpc-service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,10 @@ export class FsManagerRPCService extends RPCServiceOverIPC {
107107
"duplicateEnvironment",
108108
this.fsManager.duplicateEnvironment.bind(this.fsManager)
109109
);
110+
111+
this.exposeMethodOverIPC(
112+
"updateCollectionDescription",
113+
this.fsManager.updateCollectionDescription.bind(this.fsManager)
114+
);
110115
}
111116
}

src/renderer/actions/local-sync/fs-manager.ts

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import {
1717
COLLECTION_VARIABLES_FILE,
1818
CONFIG_FILE,
19+
DESCRIPTION_FILE,
1920
ENVIRONMENT_VARIABLES_FOLDER,
2021
GLOBAL_ENV_FILE,
2122
} from "./constants";
@@ -34,7 +35,13 @@ import {
3435
sanitizeFsResourceList,
3536
writeContent,
3637
} from "./fs-utils";
37-
import { ApiRecord, Config, EnvironmentRecord, Variables } from "./schemas";
38+
import {
39+
ApiRecord,
40+
Config,
41+
Description,
42+
EnvironmentRecord,
43+
Variables,
44+
} from "./schemas";
3845
import {
3946
API,
4047
APIEntity,
@@ -354,7 +361,6 @@ export class FsManager {
354361
if (createResult.type === "error") {
355362
return createResult;
356363
}
357-
358364
return parseFolderToCollection(this.rootPath, resource);
359365
} catch (e: any) {
360366
return {
@@ -480,6 +486,50 @@ export class FsManager {
480486
}
481487
}
482488

489+
async updateCollectionDescription(
490+
id: string,
491+
description: string
492+
): Promise<FileSystemResult<string>> {
493+
try {
494+
const descriptionFileResource = this.createResource({
495+
id: getIdFromPath(appendPath(id, DESCRIPTION_FILE)),
496+
type: "file",
497+
});
498+
if (!description.length) {
499+
const deleteResult = await deleteFsResource(descriptionFileResource);
500+
if (deleteResult.type === "error") {
501+
return deleteResult;
502+
}
503+
return {
504+
type: "success",
505+
content: "",
506+
};
507+
}
508+
509+
const writeResult = await writeContent(
510+
descriptionFileResource,
511+
description,
512+
Description,
513+
false
514+
);
515+
if (writeResult.type === "error") {
516+
return writeResult;
517+
}
518+
return {
519+
type: "success",
520+
content: description,
521+
};
522+
} catch (e: any) {
523+
return {
524+
type: "error",
525+
error: {
526+
message: e.message || "An unexpected error has occured!",
527+
path: e.path || "Unknown path",
528+
},
529+
};
530+
}
531+
}
532+
483533
async moveCollection(
484534
id: string,
485535
newParentId: string

src/renderer/actions/local-sync/fs-utils.ts

Lines changed: 92 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
import {
2323
COLLECTION_VARIABLES_FILE,
2424
CONFIG_FILE,
25+
DESCRIPTION_FILE,
2526
DS_STORE_FILE,
2627
ENVIRONMENT_VARIABLES_FOLDER,
2728
GLOBAL_CONFIG_FILE_NAME,
@@ -36,6 +37,7 @@ import {
3637
Variables,
3738
EnvironmentVariableType,
3839
GlobalConfig,
40+
Description,
3941
} from "./schemas";
4042
import { Stats } from "node:fs";
4143

@@ -198,28 +200,35 @@ export async function copyRecursive<T extends FsResource>(
198200
}
199201
}
200202

201-
export function serializeContentForWriting(content: Record<any, any>) {
203+
export function serializeContentForWriting(content: string | Record<any, any>) {
204+
if (typeof content === "string") {
205+
return content;
206+
}
202207
return JSON.stringify(content, null, 2);
203208
}
204209

205210
export async function writeContent<T extends TSchema>(
206211
resource: FileResource,
207-
content: Record<any, any>,
208-
validator: T
212+
content: string | Record<any, any>,
213+
validator: T,
214+
parseAsJson = true
209215
): Promise<FileSystemResult<{ resource: FileResource }>> {
210216
try {
211217
const serializedContent = serializeContentForWriting(content);
212-
const parsedContentResult = parseContent(serializedContent, validator);
213-
if (parsedContentResult.type === "error") {
214-
return {
215-
type: "error",
216-
error: {
217-
message: parsedContentResult.error.message,
218-
path: resource.path,
219-
},
220-
};
218+
if (parseAsJson) {
219+
const parsedContentResult = parseContent(serializedContent, validator);
220+
if (parsedContentResult.type === "error") {
221+
return {
222+
type: "error",
223+
error: {
224+
message: parsedContentResult.error.message,
225+
path: resource.path,
226+
},
227+
};
228+
}
221229
}
222-
console.log('writing at', resource.path);
230+
231+
console.log("writing at", resource.path);
223232
await fsp.writeFile(resource.path, serializedContent);
224233
return {
225234
type: "success",
@@ -231,7 +240,7 @@ export async function writeContent<T extends TSchema>(
231240
return {
232241
type: "error",
233242
error: {
234-
message: e.message || "An unexpected error has occured!",
243+
message: e.message || "An unexpected error has occurred!",
235244
path: resource.path,
236245
},
237246
};
@@ -241,10 +250,17 @@ export async function writeContent<T extends TSchema>(
241250
export async function parseFile<T extends TSchema>(params: {
242251
resource: FileResource;
243252
validator: T;
253+
parseAsJson?: boolean;
244254
}): Promise<FileSystemResult<Static<T>>> {
245-
const { resource, validator } = params;
255+
const { resource, validator, parseAsJson = true } = params;
246256
try {
247257
const content = (await fsp.readFile(resource.path)).toString();
258+
if (!parseAsJson) {
259+
return {
260+
type: "success",
261+
content,
262+
} as FileSystemResult<Static<T>>;
263+
}
248264
const parsedContentResult = parseContent(content, validator);
249265
if (parsedContentResult.type === "error") {
250266
return {
@@ -440,46 +456,88 @@ function getCollectionId(rootPath: string, fsResource: FsResource) {
440456
return getIdFromPath(parentPath);
441457
}
442458

443-
export async function parseFolderToCollection(
459+
async function getCollectionVariables(
444460
rootPath: string,
445461
folder: FolderResource
446-
): Promise<FileSystemResult<Collection>> {
462+
): Promise<FileSystemResult<Static<typeof Variables>>> {
447463
const varsPath = appendPath(folder.path, COLLECTION_VARIABLES_FILE);
448464
const collectionVariablesExist = await fsp
449465
.lstat(varsPath)
450466
.then((stats) => stats.isFile())
451467
.catch(() => false);
452468

453-
const collectionVariablesResult = await (async () => {
454-
if (collectionVariablesExist) {
455-
return parseFile({
456-
resource: createFsResource({
457-
rootPath,
458-
path: varsPath,
459-
type: "file",
460-
}),
461-
validator: Variables,
462-
});
463-
}
469+
if (collectionVariablesExist) {
470+
return parseFile({
471+
resource: createFsResource({
472+
rootPath,
473+
path: varsPath,
474+
type: "file",
475+
}),
476+
validator: Variables,
477+
});
478+
}
464479

465-
return {
466-
type: "success",
467-
content: {},
468-
} as FileSystemResult<Static<typeof Variables>>;
469-
})();
480+
return {
481+
type: "success",
482+
content: {},
483+
} as FileSystemResult<Static<typeof Variables>>;
484+
}
485+
486+
async function getDescription(
487+
rootPath: string,
488+
folder: FolderResource
489+
): Promise<FileSystemResult<string>> {
490+
const descriptionPath = appendPath(folder.path, DESCRIPTION_FILE);
491+
const descriptionFileExists = await fsp
492+
.lstat(descriptionPath)
493+
.then((stats) => stats.isFile())
494+
.catch(() => false);
495+
496+
if (descriptionFileExists) {
497+
return parseFile({
498+
resource: createFsResource({
499+
rootPath,
500+
path: descriptionPath,
501+
type: "file",
502+
}),
503+
validator: Description,
504+
parseAsJson: false,
505+
});
506+
}
470507

508+
return {
509+
type: "success",
510+
content: "",
511+
};
512+
}
513+
514+
export async function parseFolderToCollection(
515+
rootPath: string,
516+
folder: FolderResource
517+
): Promise<FileSystemResult<Collection>> {
518+
const collectionVariablesResult = await getCollectionVariables(
519+
rootPath,
520+
folder
521+
);
471522
if (collectionVariablesResult.type === "error") {
472523
return collectionVariablesResult;
473524
}
474525

526+
const descriptionFileResult = await getDescription(rootPath, folder);
527+
if (descriptionFileResult.type === "error") {
528+
return descriptionFileResult;
529+
}
530+
475531
const collectionVariables = collectionVariablesResult.content;
532+
const collectionDescription = descriptionFileResult.content;
476533

477534
const collection: Collection = {
478535
type: "collection",
479536
id: getIdFromPath(folder.path),
480537
name: getNameOfResource(folder),
481538
collectionId: getCollectionId(rootPath, folder),
482539
variables: collectionVariables,
540+
description: collectionDescription,
483541
};
484542

485543
const result: FileSystemResult<Collection> = {
@@ -540,6 +598,7 @@ export function sanitizeFsResourceList(
540598
const checks: ((resource: FsResource) => boolean)[] = [
541599
(resource) => resource.path !== appendPath(rootPath, CONFIG_FILE),
542600
(resource) => !resource.path.endsWith(COLLECTION_VARIABLES_FILE),
601+
(resource) => !resource.path.endsWith(DESCRIPTION_FILE),
543602
(resource) => !resource.path.includes(DS_STORE_FILE),
544603
];
545604
if (type === "api") {

src/renderer/actions/local-sync/schemas.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ interface KeyValuePair {
4040
type?: string;
4141
}
4242

43+
export const Description = Type.String();
44+
4345
export const ApiRecord = Type.Object({
4446
name: Type.String(),
4547
url: Type.String(),

src/renderer/actions/local-sync/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export type Collection = {
3535
id: string;
3636
name: string;
3737
variables?: Record<string, any>;
38+
description?: string;
3839
};
3940

4041
export type API = {

0 commit comments

Comments
 (0)