Skip to content
Merged
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rriv-cli",
"version": "2.17.13",
"version": "2.18.0-preview-share.2",
"description": "rriv cross-platform cli client",
"bin": "./dist/index.cjs",
"engines": {
Expand Down
28 changes: 25 additions & 3 deletions src/api/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const getContexts = async (body: {
};

export const getContextByName = async (
body: ContextNameRequest
body: ContextNameRequest,
): Promise<Context> => {
const { contextName } = body;
const response = await rrivApiAxios.get(`/context?name=${contextName}`, {});
Expand All @@ -24,7 +24,7 @@ export const getContextByName = async (
};

export const createContext = async (
body: ContextNameRequest
body: ContextNameRequest,
): Promise<Context> => {
const { contextName } = body;
const response = await rrivApiAxios.post(`/context`, { name: contextName });
Expand All @@ -38,8 +38,30 @@ export const deleteContext = async (body: IdRequest): Promise<void> => {
};

export const updateContext = async (
body: IdRequest & { end?: boolean }
body: IdRequest & { end?: boolean },
): Promise<void> => {
const { id, end } = body;
await rrivApiAxios.patch(`/context/${id}`, { end });
};

export const shareContext = async (
body: IdRequest & { email: string },
): Promise<void> => {
const { id, email } = body;
await rrivApiAxios.post(`/context/${id}/share `, { email });
};

export const getShareRecipients = async (
body: IdRequest,
): Promise<
{ id: string; firstName: string; lastName: string; email: string }[]
> => {
const { id } = body;
const response = await rrivApiAxios.get(`/context/${id}/share `);
return response.data;
};

export const getSharedContexts = async () => {
const response = await rrivApiAxios.get(`/context/shared`);
return response.data;
};
4 changes: 4 additions & 0 deletions src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export interface Context {
accountId: string;
startedAt: string;
endedAt: string;
Account?: {
id: string;
email: string;
};
}

export interface DeviceContextRequest {
Expand Down
3 changes: 2 additions & 1 deletion src/commands/connect/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ export const connectAction = async (options: any) => {
);
pullConfig = true;
} catch (e: any) {
console.log("accessing device as guest...\n");
console.log("accessing device as guest...");
await errorHandler({ error: e, doNothing: true });
if (e?.response?.data?.message === "device bound to another user") {
db.update((data) => {
data[user.email][user.env].device = {
Expand Down
2 changes: 2 additions & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { makeLibraryCommand } from "./library/index.ts";
import { makeSendCommand } from "./send/index.ts";
import { makeLogsCommand } from "./logs_/index.ts";
import { makeTelemetryCommand } from "./telemetry/index.ts";
import { makeShareCommand } from "./share/index.ts";

export const initializeCommands = (cli: Command) => {
makeWatchCommand(cli);
Expand All @@ -43,4 +44,5 @@ export const initializeCommands = (cli: Command) => {
makeLibraryCommand(cli);
makeLogsCommand(cli);
makeTelemetryCommand(cli);
makeShareCommand(cli);
};
38 changes: 38 additions & 0 deletions src/commands/share/action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
shareContext,
getContextShareRecipients,
getSharedContexts,
} from "../../modules/context/context.service.ts";
import { oraPromise } from "../../util/ora-promise.ts";

export const shareAction = async (
obj: string,
identifier: string,
email: string,
) => {
const body = { identifier, email };
if (obj === "device") {
// await oraPromise(() => shareDevice(body));
} else if (obj === "context") {
await oraPromise(() => shareContext(body));
}
};

export const listShareRecipientsAction = async (
obj: string,
identifier: string,
) => {
if (identifier) {
if (obj === "device") {
// await oraPromise(() => shareDevice(body));
} else if (obj === "context") {
await oraPromise(() => getContextShareRecipients({ identifier }));
}
} else {
if (obj === "device") {
// await oraPromise(() => shareDevice(body));
} else if (obj === "context") {
await oraPromise(() => getSharedContexts());
}
}
};
19 changes: 19 additions & 0 deletions src/commands/share/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Argument, Command } from "commander";
import { listShareRecipientsAction, shareAction } from "./action.ts";

export const makeShareCommand = (cli: Command) => {
const shareCommand = cli.command("share");

shareCommand
.addArgument(new Argument("object", "resource").choices(["context"]))
.argument("identifier")
.argument("email")
.description("share access to resource")
.action(shareAction);

shareCommand
.command("list")
.addArgument(new Argument("object", "resource").choices(["context"]))
.argument("[identifier]")
.action(listShareRecipientsAction);
};
66 changes: 55 additions & 11 deletions src/modules/context/context.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,27 @@ import {
updateContext,
deleteContext as deleteContextApiCall,
createContext as createContextApiCall,
shareContext as shareContextApiCall,
getShareRecipients,
getSharedContexts as getSharedContextsApiCall,
} from "../../api/context.ts";
import db from "../../db/db.ts";
import { pronounce } from "../../util/console-log.ts";
import { getActiveUser } from "../../util/get-logged-in-user.ts";

const getValidContextByName = async (name: string) => {
const context = await getContextByName({
contextName: name,
});
if (!context) {
throw new Error("context specified does not exist");
}
if (context.endedAt) {
throw new Error("context specified has already ended");
}
return context;
};

export const endContext = async (name?: string) => {
const {
context: { id },
Expand Down Expand Up @@ -58,19 +74,23 @@ export const listContexts = async (options: {

const userContexts = await getContexts({ name, search });
if (userContexts.length) {
const table = new Table({ head: ["name", "startedAt", "endedAt"] });
for (const { id, name, startedAt, endedAt } of userContexts) {
const table = new Table({
head: ["name", "startedAt", "endedAt", "owner"],
});
for (const { id, name, startedAt, endedAt, Account } of userContexts) {
if (id === existingContextId) {
table.push([
pronounce(name),
pronounce(new Date(startedAt).toISOString()),
pronounce(endedAt ? new Date(endedAt).toISOString() : ""),
pronounce(Account?.email || ""),
]);
} else {
table.push([
name,
new Date(startedAt).toISOString(),
endedAt ? new Date(endedAt).toISOString() : "",
Account?.email,
]);
}
}
Expand All @@ -82,16 +102,8 @@ export const listContexts = async (options: {

export const useContext = async (name: string) => {
const { email, env } = getActiveUser();
const context = await getValidContextByName(name);

const context = await getContextByName({
contextName: name,
});
if (!context) {
throw new Error("context specified does not exist");
}
if (context.endedAt) {
throw new Error("context specified has already ended");
}
db.update((data) => {
data[email][env].context = {
id: context.id,
Expand Down Expand Up @@ -140,3 +152,35 @@ export const createContext = async (name: string) => {
await createContextApiCall({ contextName: name });
console.log("context created successfully");
};

export const shareContext = async (body: {
identifier: string;
email: string;
}) => {
const { identifier, email } = body;
const context = await getValidContextByName(identifier);
await shareContextApiCall({ email, id: context.id });
};

export const getContextShareRecipients = async (body: {
identifier: string;
}) => {
const { identifier } = body;
const context = await getValidContextByName(identifier);
const contexts = await getShareRecipients({ id: context.id });
const table = new Table({ head: ["id", "name", "email"] });
for (const { id, firstName, lastName, email } of contexts) {
table.push([id, `${firstName} ${lastName}`, email]);
}
console.log(table.toString());
};

export const getSharedContexts = async () => {
const contexts = await getSharedContextsApiCall();

const table = new Table({ head: ["id", "name", "startedAt", "endedAt"] });
for (const { id, name, startedAt, endedAt } of contexts) {
table.push([id, name, startedAt, endedAt]);
}
console.log(table.toString());
};
2 changes: 2 additions & 0 deletions src/pre-action/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export const preAction = async (
if (
!(
commandName === "rrivctl" ||
commandName === "share" ||
(commandName === "list" && commandParentName === "share") ||
(commandName === "list" && args[0] === "device") ||
(commandName === "send" && args[0] === "command") ||
(commandName === "device" && commandParentName === "provision") ||
Expand Down
1 change: 1 addition & 0 deletions src/repl/process-repl-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export async function processReplCommand(
commandName === "history" ||
commandName === "logs" ||
commandName === "library" ||
commandName === "share" ||
commandName === "firmware"
)
) {
Expand Down
1 change: 1 addition & 0 deletions src/util/bind-device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export const bindDevice = async (body: {
serialNumber: string;
}): Promise<Device> => {
const device = await DeviceApiCalls.bindDevice({ ...body });
await new Promise((r) => setTimeout(r, 3000)); // wait time for auth service sync
return device;
};