Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ Beak is a simple, extensible, and powerful API creation and management tool. Bui

Beak includes:
- Powerful feature set for creating APIs interactions
- Realtime values for dynamic variable replacement
- Extensions API to create custom realtime values
- Variables, which allow you to use dynamic values in requests
- Variable Sets, which allow you to group variables together and easily switch between sets
- An extensions API to create custom Beak Variables
- Un-opinionated project syncing, just use the version control of your choice
- Beautiful design language
- And of course, fully cross platform
Expand Down
5 changes: 2 additions & 3 deletions apps-host/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"description": "A feathery cross-platform API crafting tool",
"version": "1.1.7-beta.9",
"private": true,
"type": "module",
"author": {
"name": "Alexander Forbes-Reed (0xdeafcafe)",
"email": "info@getbeak.app"
Expand Down Expand Up @@ -46,8 +45,8 @@
},
"devDependencies": {
"@electron/notarize": "^2.5.0",
"@getbeak/types": "^1.0.0",
"@getbeak/types-realtime-value": "^1.0.0",
"@getbeak/types": "^2.1.0",
"@getbeak/types-variables": "^2.1.0",
"@types/electron-devtools-installer": "^2.2.5",
"@types/fs-extra": "^11.0.4",
"@types/lodash.clonedeep": "^4.5.9",
Expand Down
6 changes: 3 additions & 3 deletions apps-host/electron/scripts/notarize.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import { notarize } from '@electron/notarize';
import path from 'path';
const { notarize } = require('@electron/notarize');
const path = require('path');

export default async function notarizing(context) {
module.exports = async function notarizing(context) {
const { electronPlatformName, appOutDir } = context;

if (electronPlatformName !== 'darwin')
Expand Down
8 changes: 4 additions & 4 deletions apps-host/electron/src/augmentations.d.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import type { Context } from '@getbeak/types/values';

declare module '@getbeak/types-realtime-value' {
declare module '@getbeak/types-variables' {
interface GenericDictionary {
[k: string]: any;
}

interface RealtimeValueBase {
interface VariableBase {
type: string;
external: boolean;
}

interface RealtimeValue<TPayload extends GenericDictionary> {
interface Variable<TPayload extends GenericDictionary> {

/**
* Gets the string value of the value, given the payload body
Expand All @@ -21,7 +21,7 @@ declare module '@getbeak/types-realtime-value' {
getValue: (ctx: Context, payload: TPayload, recursiveDepth: number) => Promise<string>;
}

interface EditableRealtimeValue<TPayload extends GenericDictionary> {
interface EditableVariable<TPayload extends GenericDictionary> {

/**
* Gets the string value of the value, given the payload body
Expand Down
4 changes: 2 additions & 2 deletions apps-host/electron/src/ipc-layer/encryption-service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IpcEncryptionServiceMain } from '@beak/common/ipc/encryption';
import { clipboard, ipcMain } from 'electron';
import { ValueParts } from 'packages/types/values';
import { ValueSections } from 'packages/types/values';

import getBeakHost from '../host';
import { getProjectId } from './utils';
Expand Down Expand Up @@ -58,7 +58,7 @@ service.registerEncryptObject(async (event, { iv, payload }) => {
return await getBeakHost().providers.aes.encryptString(json, encryption.key, iv);
});

service.registerDecryptObject(async (event, { iv, payload }): Promise<ValueParts> => {
service.registerDecryptObject(async (event, { iv, payload }): Promise<ValueSections> => {
const projectId = getProjectId(event);
const encryption = await getBeakHost().providers.credentials.getProjectEncryption(projectId);

Expand Down
42 changes: 25 additions & 17 deletions apps-host/electron/src/lib/extension/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { ensureWithinProject } from '@beak/apps-host-electron/ipc-layer/fs-service';
import { getProjectFilePathWindowMapping } from '@beak/apps-host-electron/ipc-layer/fs-shared';
import { ExtensionsMessages, IpcExtensionsServiceMain, RtvParseValuePartsResponse } from '@beak/common/ipc/extensions';
import { ExtensionsMessages, IpcExtensionsServiceMain, RtvParseValueSectionsResponse } from '@beak/common/ipc/extensions';
import { IpcEvent, RequestPayload } from '@beak/common/ipc/ipc';
import { RealtimeValueExtension } from '@beak/common/types/extensions';
import { VariableExtension } from '@beak/common/types/extensions';
import Squawk from '@beak/common/utils/squawk';
import ksuid from '@beak/ksuid';
import { Context, ValueParts } from '@getbeak/types/values';
import { EditableRealtimeValue } from '@getbeak/types-realtime-value/';
import { Context, ValueSections } from '@getbeak/types/values';
import { EditableVariable } from '@getbeak/types-variables';
import { ipcMain, WebContents } from 'electron';
import fs from 'fs-extra';
import clone from 'lodash.clonedeep';
Expand All @@ -26,7 +26,7 @@ interface RtvExtensionStorage {
scriptContent: string;
vm: NodeVM;
script: VMScript;
extension: EditableRealtimeValue<any, any>;
extension: EditableVariable<any, any>;
}

const logger = new Logger({ name: 'extensions' });
Expand All @@ -41,7 +41,7 @@ export default class ExtensionManager {
this.extensionService = extensionService;
}

async registerRtv(event: IpcEvent, projectId: string, extensionPath: string): Promise<RealtimeValueExtension> {
async registerRtv(event: IpcEvent, projectId: string, extensionPath: string): Promise<VariableExtension> {
if (!this.projectExtensions[projectId])
this.projectExtensions[projectId] = {};

Expand All @@ -57,7 +57,7 @@ export default class ExtensionManager {
sandbox: {
beakApi: {
log: (level: LogLevel, message: string) => (logger[level] ?? logger.warn)(message),
parseValueParts: (_ctx: unknown, _parts: unknown, _recursiveSet: unknown) => [],
parseValueSections: (_ctx: unknown, _parts: unknown, _recursiveSet: unknown) => [],
},
},
});
Expand All @@ -71,7 +71,7 @@ export default class ExtensionManager {

const compiledScript = new VMScript(scriptContent);
const extensionContext = extensionVm.run(compiledScript);
const extension = extensionContext?.default as EditableRealtimeValue<any>;
const extension = extensionContext?.default as EditableVariable<any>;

this.validateExtensionSignature(extension);
this.projectExtensions[projectId][type] = {
Expand All @@ -88,7 +88,7 @@ export default class ExtensionManager {
version,
filePath: extensionPath,
valid: true,
realtimeValue: {
variable: {
type,
external: true,
name: extension.name,
Expand Down Expand Up @@ -119,11 +119,11 @@ export default class ExtensionManager {
) {
const { vm, extension } = this.getExtensionContext(projectId, type);

vm.sandbox.beakApi.parseValueParts = async (ctx: Context, parts: ValueParts) => {
vm.sandbox.beakApi.parseValueSections = async (ctx: Context, parts: ValueSections) => {
const uniqueSessionId = ksuid.generate('rtvparsersp').toString();

// send IPC request
this.extensionService.rtvParseValueParts(webContents, {
this.extensionService.rtvParseValueSections(webContents, {
uniqueSessionId,
context: ctx,
parts,
Expand All @@ -132,9 +132,9 @@ export default class ExtensionManager {

return await new Promise(resolve => {
ipcMain.on(this.extensionService.getChannel(), async (_event, message) => {
const { code, payload } = message as RequestPayload<RtvParseValuePartsResponse>;
const { code, payload } = message as RequestPayload<RtvParseValueSectionsResponse>;

if (code !== ExtensionsMessages.RtvParseValuePartsResponse)
if (code !== ExtensionsMessages.RtvParseValueSectionsResponse)
return;

if (payload.uniqueSessionId !== uniqueSessionId)
Expand All @@ -157,13 +157,21 @@ export default class ExtensionManager {

async rtvEditorLoad(projectId: string, type: string, context: Context, payload: unknown) {
const { extension } = this.getExtensionContext(projectId, type);

if (extension.editor.load === void 0)
return payload;

const editorState = await extension.editor.load(context, payload);

return clone(editorState);
}

async rtvEditorSave(projectId: string, type: string, context: Context, existingPayload: unknown, state: unknown) {
const { extension } = this.getExtensionContext(projectId, type);

if (extension.editor.save === void 0)
return state;

const payload = await extension.editor.save(context, existingPayload, state);

return clone(payload);
Expand All @@ -175,7 +183,7 @@ export default class ExtensionManager {
if (!extensionStorage)
throw new Squawk('unknown_registered_extension', { projectId, type });

extensionStorage.vm.sandbox.beakApi.parseValueParts = () => [];
extensionStorage.vm.sandbox.beakApi.parseValueSections = () => [];

return { vm: extensionStorage.vm, extension: extensionStorage.extension };
}
Expand All @@ -185,11 +193,11 @@ export default class ExtensionManager {
const packageJson = await fs.readJson(packageJsonPath);
const { name, version, beakExtensionType, main } = packageJson;

if (beakExtensionType !== 'realtime-value') {
if (beakExtensionType !== 'variable') {
throw new Squawk('invalid_extension_type', {
extensionPath,
packageJsonKey: 'beakExtensionType',
expected: 'realtime-value',
expected: 'variable',
actual: beakExtensionType ?? '[missing]',
});
}
Expand Down Expand Up @@ -235,7 +243,7 @@ export default class ExtensionManager {
return { main, name, scriptPath, version };
}

private validateExtensionSignature(extension: EditableRealtimeValue<any>) {
private validateExtensionSignature(extension: EditableVariable<any>) {
if (!('name' in extension))
throw new Squawk('incorrect_extension_signature', { key: 'name', reason: 'missing' });
if (typeof extension.name !== 'string')
Expand Down
4 changes: 2 additions & 2 deletions apps-host/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"@beak/ksuid": "*",
"@beak/ui": "*",
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
"@getbeak/types": "^1.0.0",
"@getbeak/types-realtime-value": "^1.0.0",
"@getbeak/types": "^2.1.0",
"@getbeak/types-variables": "^2.1.0",
"@isomorphic-git/lightning-fs": "^4.6.0",
"path-browserify": "^1.0.1"
},
Expand Down
10 changes: 5 additions & 5 deletions apps-host/web/src/augmentations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,28 @@ declare module 'electron' {
}
}

declare module '@getbeak/types-realtime-value' {
declare module '@getbeak/types-variables' {
interface GenericDictionary {
[k: string]: any;
}

interface RealtimeValueBase {
interface VariableBase {
type: string;
external: boolean;
}

interface RealtimeValue<TPayload extends GenericDictionary> {
interface Variable<TPayload extends GenericDictionary> {

/**
* Gets the string value of the value, given the payload body
* @param {Context} ctx The project context.
* @param {TPayload} payload This instance of the value's payload data.
* @param {number} recursiveDepth The current depth of realtime value recursion.
* @param {number} recursiveDepth The current depth of value recursion.
*/
getValue: (ctx: Context, payload: TPayload, recursiveDepth: number) => Promise<string>;
}

interface EditableRealtimeValue<TPayload extends GenericDictionary> {
interface EditableVariable<TPayload extends GenericDictionary> {

/**
* Gets the string value of the value, given the payload body
Expand Down
4 changes: 2 additions & 2 deletions apps-host/web/src/ipc/encryption-service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IpcEncryptionServiceMain } from '@beak/common/ipc/encryption';
import { ValueParts } from 'packages/types/values';
import { ValueSections } from 'packages/types/values';

import getBeakHost from '../host';
import { webIpcMain } from './ipc';
Expand Down Expand Up @@ -72,7 +72,7 @@ service.registerEncryptObject(async (_event, { iv, payload }) => {
return await getBeakHost().providers.aes.encryptString(json, encryption.key, iv);
});

service.registerDecryptObject(async (_event, { iv, payload }): Promise<ValueParts> => {
service.registerDecryptObject(async (_event, { iv, payload }): Promise<ValueSections> => {
const projectId = getCurrentProjectId();

if (!projectId) return ['Project not loaded'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const FeatureOverview: React.FC<React.PropsWithChildren<unknown>> = () => {
{'Powerful feature set'}
</CardTitle>
<CardBody>
{'From support for large API projects, realtime values, '}
{'From support for large API projects, variables, '}
{'rich value editors, to baked in project encryption, for '}
{'your most secretive of secrets 🤫.'}
</CardBody>
Expand All @@ -48,12 +48,12 @@ const FeatureOverview: React.FC<React.PropsWithChildren<unknown>> = () => {
/>
</CardIcons>
<CardTitle>
{'Realtime values'}
{'Variables'}
</CardTitle>
<CardBody>
{'Realtime values are inline variables you can insert into '}
{'any part of your request that are calculated in real time '}
{'as you type, and as you send requests. '}
{'Variables are inline values you can insert into any part '}
{'of your request that are calculated dynamically in real '}
{'time as you type, and as you send requests.'}
</CardBody>
</Card>
<Card>
Expand Down Expand Up @@ -105,7 +105,7 @@ const FeatureOverview: React.FC<React.PropsWithChildren<unknown>> = () => {
</CardTitle>
<CardBody>
{'Coming soon, is an expansive extensions API, allowing you '}
{'to create custom extensions for realtime values, '}
{'to create custom extensions for variables, '}
{'API workflows, and more. Make Beak your own.'}
</CardBody>
</Card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const versions: Record<Version, VersionInformation> = {
items: [
'Requests',
'Responses',
'Realtime values',
'Variables',
'Literally everything',
],
},
Expand All @@ -30,7 +30,7 @@ const versions: Record<Version, VersionInformation> = {
items: [
'Requests',
'Responses',
'Realtime values',
'Variables',
'Literally everything',
],
},
Expand All @@ -40,7 +40,7 @@ const versions: Record<Version, VersionInformation> = {
items: [
'Requests',
'Responses',
'Realtime values',
'Variables',
'Literally everything',
],
},
Expand Down
7 changes: 4 additions & 3 deletions docs/ksuid-resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ While we don't use the environment portion of the KSUID (for obvious reasons), w
| `flight` | A flight (or historical request) made by Beak. |
| `query` | A query item, used in the request info. |
| `header` | A header item, used in the request info. |
| `item` | An item in a variable group. Closely related to `group`. |
| `group` | A group in a variable group. Closely related to `item`. |
| `value` | A value linking an `item` and a `group` from a variable group. |
| `item` | An item in a variable set. Closely related to `set`. |
| `group` | A group in a variable group. Legacy, this is called `set` going forward. Closely related to `item`. |
| `set` | A set in a variable set. Closely related to `item`. |
| `value` | A value linking an `item` and a `set` from a variable set. |
4 changes: 2 additions & 2 deletions packages/common-host/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"dependencies": {
"@beak/common": "*",
"@beak/ksuid": "*",
"@getbeak/types": "^1.0.0",
"@getbeak/types-realtime-value": "^1.0.0"
"@getbeak/types": "^2.1.0",
"@getbeak/types-variables": "^2.1.0"
}
}
4 changes: 2 additions & 2 deletions packages/common-host/src/project/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export default class BeakExtensions extends BeakBase {
'',
'## Getting started',
'Below are some useful resources for getting started with Beak\'s extensions',
'- [Extensions manual](https://getbeak.notion.site/Extensions-realtime-values-4c16ca640b35460787056f8be815b904)',
'- [GitHub extension template](https://github.com/getbeak/realtime-value-extension-template)',
'- [Extensions manual](https://www.notion.so/getbeak/Extensions-4c16ca640b35460787056f8be815b904)',
'- [GitHub extension template](https://github.com/getbeak/extension-variable-template)',
'',
].join('\n');
}
Expand Down
Loading
Loading