Skip to content

Commit

Permalink
feat(odc): command-specific configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
dlenroc authored Nov 18, 2023
1 parent 2b1b141 commit 566d124
Show file tree
Hide file tree
Showing 21 changed files with 309 additions and 199 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
"devDependencies": {
"@tsconfig/node20": "^20.1.2",
"@tsconfig/strictest": "^2.0.2",
"@types/node": "^20.8.10",
"@types/sinon": "^17.0.0",
"@types/node": "^20.9.1",
"@types/sinon": "^17.0.1",
"sinon": "^17.0.1",
"tsx": "^3.14.0",
"tsx": "^4.1.3",
"typescript": "^5.2.2"
}
}
48 changes: 4 additions & 44 deletions packages/odc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,55 +13,15 @@ npm install @dlenroc/roku-odc
> ⚠️ `extend(app)` must be used to inject backend into your application
```typescript
import fs from 'fs';
import SDK, { DeveloperServer, ODC } from '@dlenroc/roku';
import { ODCExecutor, getRegistry } from '@dlenroc/roku-odc';

// const odc = new ODC('<ip>');
const odc = new ODC({ address: 'http://<ip>:8061' });

// const developerServer = new DeveloperServer('<ip>', '<username>', '<password>');
const developerServer = new DeveloperServer({ address: 'http://<ip>', username: '<username>', password: '<password>' });

const app = fs.readFileSync('<path_to_channel>');
const patchedApp = await odc.extend(app);
await developerServer.install(patchedApp);
await odc.getRegistry();
const ctx = new ODCExecutor({ address: '<ip>:8061' });
const registry = await getRegistry(ctx);
console.log(registry);
```

---

```typescript
extend(app: Buffer): Promise<Buffer>
```

```typescript
getAppUI(fields?: Record<string, string[]>): Promise<string>
```

```typescript
getRegistry(): Promise<Record<string, Record<string, string>>>
```

```typescript
patchRegistry(changes: Record<string, null | Record<string, any>>): Promise<void>
```

```typescript
clearRegistry(): Promise<void>
```

```typescript
getFiles(path: string): Promise<(File | Directory)[]>
```

```typescript
pullFile(path: string): Promise<Buffer>
```

```typescript
pushFile(path: string, content: string | Buffer): Promise<void>
```

## Launch parameters

All of the above commands require the application to be up and running, but some of them can also be run using [ECP](/packages/ecp#readme) during startup
Expand Down
6 changes: 3 additions & 3 deletions packages/odc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
"dist",
"src"
],
"scripts": {
"build": "tsc --build --force tsconfig.build.json"
},
"dependencies": {
"jszip": "^3.10.1",
"node-fetch": "^3.3.2"
"jszip": "^3.10.1"
}
}
14 changes: 14 additions & 0 deletions packages/odc/src/Executor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/// <reference types="node" />

export interface Executor<Config = {}> {
execute(
request: {
method: string;
path: string;
headers?: null | undefined | Record<string, string>;
params?: null | undefined | Record<string, unknown>;
data?: null | undefined | RequestInit['body'];
},
config?: Config
): Promise<Response>;
}
109 changes: 0 additions & 109 deletions packages/odc/src/ODC.ts

This file was deleted.

98 changes: 98 additions & 0 deletions packages/odc/src/ODCExecutor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import type { Executor } from './Executor.js';
import { ODCError } from './ODCError.js';

type ODCConfig = {
address: string;
signal?: AbortSignal;
};

type ODCExecutorConfig = {
signal?: AbortSignal;
};

export class ODCExecutor implements Executor<ODCExecutorConfig> {
#config: ODCConfig;

constructor(config: ODCConfig) {
this.#config = config;
}

async execute(
request: {
method: string;
path: string;
headers?: null | undefined | Record<string, string>;
params?: null | undefined | Record<string, unknown>;
data?: null | undefined | RequestInit['body'];
},
config?: ODCExecutorConfig
): Promise<Response> {
const signal =
this.#config.signal && config?.signal
? // @ts-ignore
AbortSignal.any([this.#config.signal, config.signal])
: this.#config.signal || config?.signal;

let path = request.path;

if (request.params) {
const params = Object.entries(request.params).reduce(
(result, [key, value]) => {
result[key] = ['string', 'number', 'boolean'].includes(typeof value)
? value
: JSON.stringify(value);
return result;
},
{} as Record<string, any>
);

path += '?' + new URLSearchParams(params);
}

const requestInit: RequestInit = {
signal,
method: request.method,
};

if (request.headers) {
requestInit.headers = request.headers;
}

if (request.data) {
requestInit.body = request.data;
}

const response = await fetch(
this.#config.address + '/' + path,
requestInit
);

if (!response.ok) {
const json: any = await response.json();

let trace = json.backtrace?.reverse() || [];
let message =
json.message || `${request.method} /${path} -> ${response.status}`;
let error = message;

if (trace.length) {
error += '\n at ';
error += trace
.map(
(trace: any) =>
trace.function.replace(/\(.+/, '') +
' (' +
trace.filename +
':' +
trace.line_number +
')'
)
.join('\n at ');
}

throw new ODCError(error);
}

return response;
}
}
2 changes: 1 addition & 1 deletion packages/odc/src/ODCOptions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type ODCOptions = {
address: string;
signal?: AbortSignal;
}
};
9 changes: 9 additions & 0 deletions packages/odc/src/commands/clearRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Executor } from '../Executor.js';
import type { Config } from '../internal/Config.js';

export async function clearRegistry<Context extends Executor>(
ctx: Context,
config?: Config<Context>
): Promise<void> {
await ctx.execute({ method: 'DELETE', path: 'registry' }, config);
}
5 changes: 5 additions & 0 deletions packages/odc/src/commands/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import inject from '../internal/injector.js';

export async function extend(app: Buffer): Promise<Buffer> {
return await inject(app);
}
15 changes: 15 additions & 0 deletions packages/odc/src/commands/getAppUI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Executor } from '../Executor.js';
import type { Config } from '../internal/Config.js';
import type { Nullable } from '../internal/Nullable.js';

export async function getAppUI<Context extends Executor>(
ctx: Context,
params?: Nullable<{ fields?: Nullable<Record<string, string[]>> }>,
config?: Config<Context>
): Promise<string> {
const response = await ctx.execute(
{ method: 'GET', path: 'app-ui', params },
config
);
return response.text();
}
16 changes: 16 additions & 0 deletions packages/odc/src/commands/getFiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Executor } from '../Executor.js';
import type { Config } from '../internal/Config.js';
import type { Directory } from '../types/Directory.js';
import type { File } from '../types/File.js';

export async function getFiles<Context extends Executor>(
ctx: Context,
params: { path: string },
config?: Config<Context>
): Promise<(File | Directory)[]> {
const response = await ctx.execute(
{ method: 'GET', path: 'files', params },
config
);
return response.json() as any;
}
13 changes: 13 additions & 0 deletions packages/odc/src/commands/getRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Executor } from '../Executor.js';
import type { Config } from '../internal/Config.js';

export async function getRegistry<Context extends Executor>(
ctx: Context,
config?: Config<Context>
): Promise<Record<string, Record<string, string>>> {
const response = await ctx.execute(
{ method: 'GET', path: 'registry' },
config
);
return response.json() as any;
}
Loading

0 comments on commit 566d124

Please sign in to comment.