Skip to content

Commit

Permalink
Merge pull request #14 from spluxx/v0.3.2
Browse files Browse the repository at this point in the history
V0.3.2
  • Loading branch information
Inchan Hwang authored Apr 21, 2020
2 parents 2f321f4 + 810b6fb commit 273c57c
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 16 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ A [Postman](https://www.postman.com/)-like API client for [protobuf](https://dev

### Mac

[Protoman-0.3.1.dmg](https://github.com/spluxx/Protoman/releases/download/v0.3.1/Protoman-0.3.1.dmg)
[Protoman-0.3.2.dmg](https://github.com/spluxx/Protoman/releases/download/v0.3.2/Protoman-0.3.2.dmg)

### Windows

[Protoman Setup 0.3.1.exe](https://github.com/spluxx/Protoman/releases/download/v0.3.1/Protoman.Setup.0.3.1.exe) - Unlike mac, I don't currently own a license to sign the app. So it might give you some security warnings!
[Protoman Setup 0.3.2.exe](https://github.com/spluxx/Protoman/releases/download/v0.3.2/Protoman.Setup.0.3.2.exe) - Unlike mac, I don't currently own a license to sign the app. So it might give you some security warnings!

### Linux

[Protoman-0.3.1.AppImage](https://github.com/spluxx/Protoman/releases/download/v0.3.1/Protoman-0.3.1.AppImage)
[Protoman-0.3.2.AppImage](https://github.com/spluxx/Protoman/releases/download/v0.3.2/Protoman-0.3.2.AppImage)

As a fallback, you can clone the repo and run npm install && npm run build to build, and npm run start to launch the app. Or, you can actually find configurations on [electron builder](https://www.electron.build/) to get the right distribution version yourself!

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Protoman",
"version": "0.3.1",
"version": "0.3.2",
"description": "Basic Postman clone with protobuf functionalities",
"author": "Inchan Hwang, Louis Lee",
"license": "MIT",
Expand Down
25 changes: 18 additions & 7 deletions src/core/protobuf/protoParser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import protobuf from 'protobufjs';
import { ProtobufType, MessageType, EnumType, ProtoCtx } from './protobuf';
import { allPrimitiveTypes } from './primitiveTypes';
import path from 'path';

type FieldPair<T> = [string, T];
type Fields<T> = Array<FieldPair<T>>;
Expand Down Expand Up @@ -85,17 +86,27 @@ function traverseTypes(
return types;
}

function readProto(path: string): Promise<ProtobufType[]> {
return protobuf
function readProto(root: protobuf.Root, path: string): Promise<ProtobufType[]> {
return root
.load(path)
.then(traverseTypes)
.catch(err => {
throw new Error('Protobuf cannot be read');
throw new Error('Protobuf cannot be read: ' + err);
});
}

export async function readProtos(paths: ReadonlyArray<string>): Promise<[ProtobufType[], { [key: string]: string }]> {
const typeLists = await Promise.all(paths.map(readProto));
export async function readProtos(
paths: ReadonlyArray<string>,
rootPath?: string,
): Promise<[ProtobufType[], { [key: string]: string }]> {
const root = new protobuf.Root();
root.resolvePath = (origin, target): string => path.resolve(rootPath ?? origin, target);

const typeLists = [];
for (let i = 0; i < paths.length; i++) {
typeLists.push(await readProto(root, paths[i]));
}

const [types, origin] = typeLists.reduce(
(acc, typesFromFile, idx) => {
const [types, origin] = acc;
Expand All @@ -113,8 +124,8 @@ export async function readProtos(paths: ReadonlyArray<string>): Promise<[Protobu
return [types.concat(allPrimitiveTypes), origin];
}

export async function buildContext(filepaths: ReadonlyArray<string>): Promise<ProtoCtx> {
const [protoTypes, origin] = await readProtos(filepaths);
export async function buildContext(filepaths: ReadonlyArray<string>, rootPath?: string): Promise<ProtoCtx> {
const [protoTypes, origin] = await readProtos(filepaths, rootPath);
return {
types: protoTypes.reduce((acc, type) => {
acc[type.name] = type;
Expand Down
13 changes: 13 additions & 0 deletions src/core/protobuf/test/protobuf.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,16 @@ test('parser should successfully build a ProtoCtx with multiple .proto files', a
const protoCtx = await buildContext(filepaths);
expect(Object.keys(protoCtx.types).length).toBe(5 + allPrimitiveTypes.length);
});

test('parser should successfully build a ProtoCtx that imports using root directory', async () => {
const filepaths = [
resolvePath('test5/account/api/account_test.proto'),
resolvePath('test5/account/data/account.proto'),
resolvePath('test5/common/valid.proto'),
];

const rootPath = resolvePath('test5');

const protoCtx = await buildContext(filepaths, rootPath);
expect(Object.keys(protoCtx.types).length).toBe(3 + allPrimitiveTypes.length);
});
7 changes: 7 additions & 0 deletions src/core/protobuf/test/test5/account/api/account_test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";

import "account/data/account.proto";

message AccountList {
repeated account.data.Account accounts = 1;
}
13 changes: 13 additions & 0 deletions src/core/protobuf/test/test5/account/data/account.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
syntax = "proto3";

package account.data;

import "common/valid.proto";

message Account {
int64 account_id = 1;
string first_name = 2 [(valid.pattern) = "[a-zA-Z]{5,20}"];
string last_name = 3 [(valid.pattern) = "[a-zA-Z]{5,20}"];
string email = 4 [(valid.email) = true];
string phone = 5 [(valid.pattern) = "[a-zA-Z]{5,20}"];
}
5 changes: 5 additions & 0 deletions src/core/protobuf/test/test5/common/valid.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
syntax = "proto3";

message Dummy {
repeated string dummies = 1;
}
22 changes: 19 additions & 3 deletions src/renderer/components/Collection/protofile/ProtofileManager.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import styled from 'styled-components';
import { Typography, List, Button, Row, Col, Checkbox, Divider, Alert } from 'antd';
import { Typography, List, Button, Row, Col, Checkbox, Divider, Alert, Input } from 'antd';
import { PlusOutlined, CloseOutlined, BuildOutlined } from '@ant-design/icons';
import { useDispatch, useSelector } from 'react-redux';
import { buildProtofiles, resetProtofileStatus } from './ProtofileManagerActions';
Expand All @@ -26,11 +26,13 @@ const ProtofileManager: React.FunctionComponent<Props> = ({ collectionName }) =>

const collection = useSelector((s: AppState) => getByKey(s.collections, collectionName));
const filepaths = collection?.protoFilepaths;
const rootPath = collection?.protoRootPath;
const buildStatus = collection?.buildStatus;
const buildError = collection?.buildError;

const [selected, setSelected] = React.useState<string[]>([]);
const [draft, setDraft] = React.useState<string[]>([]);
const [draftRootPath, setDraftRootPath] = React.useState<string>('');

const filepickerRef = React.useRef<HTMLInputElement>(null);

Expand All @@ -40,6 +42,12 @@ const ProtofileManager: React.FunctionComponent<Props> = ({ collectionName }) =>
}
}, [filepaths]);

React.useEffect(() => {
if (rootPath) {
setDraftRootPath(rootPath ?? '');
}
}, [rootPath]);

if (!collection) return null;

function handleFileInput(files: FileList | null): void {
Expand Down Expand Up @@ -75,7 +83,7 @@ const ProtofileManager: React.FunctionComponent<Props> = ({ collectionName }) =>
}

function tryBuilding(): void {
dispatch(buildProtofiles(collectionName, draft));
dispatch(buildProtofiles(collectionName, draft, draftRootPath || undefined));
}

const triggerFileDialog = (): void => filepickerRef.current?.click();
Expand Down Expand Up @@ -110,6 +118,14 @@ const ProtofileManager: React.FunctionComponent<Props> = ({ collectionName }) =>
</Button>
</div>

<div style={{ marginBottom: 8 }}>
<Input
addonBefore="proto_path"
value={draftRootPath}
onChange={(e): void => setDraftRootPath(e.target.value)}
/>
</div>

{draft.length > 0 ? (
<>
<Checkbox
Expand All @@ -135,7 +151,7 @@ const ProtofileManager: React.FunctionComponent<Props> = ({ collectionName }) =>
/>
</Col>
<Col span={23}>
<span style={{ textOverflow: 'ellipsis', width: '100%', marginLeft: 8 }}>{filepath}</span>
<p style={{ width: '100%', marginLeft: 8, marginBottom: 0 }}>{filepath}</p>
</Col>
</Row>
</List.Item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type SetProtofiles = {
type: 'SET_PROTOFILES';
collectionName: string;
filepaths: string[];
rootPath?: string;
};

const SET_PROTOFILES = 'SET_PROTOFILES';
Expand All @@ -16,6 +17,7 @@ type BuildProtofiles = {
type: 'BUILD_PROTOFILES';
collectionName: string;
filepaths: string[];
rootPath?: string;
};

const BUILD_PROTOFILES = 'BUILD_PROTOFILES';
Expand Down Expand Up @@ -60,14 +62,15 @@ export type ProtofileManagerActions =
export function buildProtofiles(
collectionName: string,
filepaths: string[],
rootPath?: string,
): ThunkAction<Promise<void>, AppState, {}, AnyAction> {
return async (dispatch): Promise<void> => {
if (filepaths) {
dispatch({ type: BUILD_PROTOFILES, collectionName, filepaths });
try {
const ctx = await buildContext(filepaths);
const ctx = await buildContext(filepaths, rootPath);
dispatch({ type: BUILD_PROTOFILES_SUCCESS, collectionName, ctx });
dispatch({ type: SET_PROTOFILES, collectionName, filepaths });
dispatch({ type: SET_PROTOFILES, collectionName, filepaths, rootPath });
} catch (err) {
dispatch({ type: BUILD_PROTOFILES_FAILURE, collectionName, err });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default function ProtofileManagerReducer(s: AppState, action: AnyAction):
const collection = getByKey(draft.collections, a.collectionName);
if (collection) {
collection.protoFilepaths = a.filepaths;
collection.protoRootPath = a.rootPath;
collection.buildError = undefined;
}
});
Expand Down
1 change: 1 addition & 0 deletions src/renderer/models/Collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Flow } from './flow';

export interface Collection {
readonly protoFilepaths: ReadonlyArray<string>;
readonly protoRootPath?: string;
readonly buildStatus: 'default' | 'building' | 'success' | 'failure';
readonly buildError: Error | undefined;
readonly protoCtx: ProtoCtx;
Expand Down
6 changes: 6 additions & 0 deletions src/renderer/redux/AppReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ function applyAll(reducers: BigReducer[]): BigReducer {
};
}

function Logger(s: AppState, a: AnyAction): AppState {
console.log(a);
return s;
}

const AppReducer = applyAll([
MessageValueViewReducer,
EnvPickerReducer,
Expand All @@ -32,6 +37,7 @@ const AppReducer = applyAll([
FlowViewReducers,
ExpectedBodyInputReducer,
BulkReducer,
// Logger,
]);

export default AppReducer;

0 comments on commit 273c57c

Please sign in to comment.