Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workbook package #3019

Draft
wants to merge 12 commits into
base: version-4
Choose a base branch
from
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions packages/graph/behaviors/prefer-async.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { TimelinePipe } from "@pnp/core";
import { InjectHeaders } from "@pnp/queryable";
import { GraphQueryable, _GraphQueryable, graphGet } from "../graphqueryable.js";
import { RichLongRunningOperation } from "@microsoft/microsoft-graph-types";

export function PreferAsync(pollIntervalMs: number = 25000, maxPolls: number = 4): TimelinePipe {

Check failure on line 6 in packages/graph/behaviors/prefer-async.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

Type number trivially inferred from a number literal, remove type annotation

Check failure on line 6 in packages/graph/behaviors/prefer-async.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

Type number trivially inferred from a number literal, remove type annotation
return (instance: _GraphQueryable) => {
instance.using(InjectHeaders({ "Prefer": "respond-async" }));

instance.on.parse(async function (url, response, result) {
if (response.status === 202) {
ChapC marked this conversation as resolved.
Show resolved Hide resolved
const opLocation = response.headers.get("Location");
const opId = opLocation.split("/").at(-1);

let succeeded = false;
const statusQuery = GraphQueryable(instance, `operations/${opId}`);
for (let i = 0; i < maxPolls; i++) {
await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
ChapC marked this conversation as resolved.
Show resolved Hide resolved

const status = await graphGet<RichLongRunningOperation>(statusQuery);
ChapC marked this conversation as resolved.
Show resolved Hide resolved
if (status.status === 'succeeded') {

Check failure on line 21 in packages/graph/behaviors/prefer-async.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

Strings must use doublequote
let resultEndpoint = status.resourceLocation.split("/").at(-1);

Check failure on line 22 in packages/graph/behaviors/prefer-async.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

'resultEndpoint' is never reassigned. Use 'const' instead
result = await graphGet(GraphQueryable(instance, resultEndpoint));
succeeded = true;
break;
} else if (status.status === 'failed') {

Check failure on line 26 in packages/graph/behaviors/prefer-async.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

Strings must use doublequote
throw status.error;
}
}
if (!succeeded) {
throw new Error(`Timed out waiting for async operation after ${pollIntervalMs * maxPolls}ms`);
}
}
return [url, response, result];
})

Check failure on line 35 in packages/graph/behaviors/prefer-async.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

Missing semicolon

return instance;
}

Check failure on line 38 in packages/graph/behaviors/prefer-async.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

Missing semicolon
}

Check failure on line 39 in packages/graph/behaviors/prefer-async.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

Newline required at end of file but not found
18 changes: 18 additions & 0 deletions packages/graph/workbooks/driveitem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { addProp } from "@pnp/queryable";
import { _DriveItem } from "../files/types.js";
import { IWorkbook, IWorkbookWithSession, Workbook } from "./types.js";
import { getWorkbookSession } from "./session.js";

declare module "../files/types.js" {
interface _DriveItem {
readonly workbook: IWorkbook;
getWorkbookSession(persistChanges: boolean): Promise<IWorkbookWithSession>;
}
interface DriveItem {
readonly workbook: IWorkbook;
getWorkbookSession(persistChanges: boolean): Promise<IWorkbookWithSession>;
}
}

addProp(_DriveItem, "workbook", Workbook);
_DriveItem.prototype.getWorkbookSession = getWorkbookSession;

Check failure on line 18 in packages/graph/workbooks/driveitem.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

Newline required at end of file but not found
11 changes: 11 additions & 0 deletions packages/graph/workbooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import "./driveitem.js";

export {

Check failure on line 3 in packages/graph/workbooks/index.ts

View workflow job for this annotation

GitHub Actions / run_pr_tests

Trailing spaces not allowed
IWorkbook,
ITable,
ITables,
ITableRow,
ITableRows,
ITableColumn,
ITableColumns
} from "./types.js";
20 changes: 20 additions & 0 deletions packages/graph/workbooks/session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { GraphQueryable, graphPost } from "../graphqueryable.js";
import { InjectHeaders, body } from "@pnp/queryable";
import { IWorkbookWithSession, WorkbookWithSession } from "./types.js";
import { _DriveItem } from "../files/types.js";
import {
WorkbookSessionInfo
} from "@microsoft/microsoft-graph-types";

export async function getWorkbookSession(this: _DriveItem, persistChanges: boolean): Promise<IWorkbookWithSession> {
ChapC marked this conversation as resolved.
Show resolved Hide resolved
const workbook = WorkbookWithSession(this);
const sessionResult = await graphPost<WorkbookSessionInfo>(
GraphQueryable(workbook, 'createSession'), body({
persistChanges
}));

if (!sessionResult.id) throw new Error("createSession did not respond with a session ID");

workbook.using(InjectHeaders({ "workbook-session-id": sessionResult.id }));
return workbook;
}
91 changes: 91 additions & 0 deletions packages/graph/workbooks/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { updateable, IUpdateable, addable, getById, IAddable, IGetById, deleteable, IDeleteable, defaultPath } from "../decorators.js";
import { _GraphCollection, graphInvokableFactory, _GraphInstance, GraphQueryable } from "../graphqueryable.js";
import {
Workbook as WorkbookType,
WorkbookTable as WorkbookTableType,
WorkbookTableRow as WorkbookTableRowType,
WorkbookTableColumn as WorkbookTableColumnType
} from "@microsoft/microsoft-graph-types";
import { graphPost } from "@pnp/graph";

@defaultPath("workbook")
export class _Workbook extends _GraphInstance<WorkbookType> {
public get tables(): ITables {
return Tables(this);
}
}
export interface IWorkbook extends _Workbook {}
export const Workbook = graphInvokableFactory<IWorkbook>(_Workbook);

export class _WorkbookWithSession extends _Workbook {
public closeSession(): Promise<void> {
return graphPost(GraphQueryable(this, "closeSession"));
}

public refreshSession(): Promise<void> {
return graphPost(GraphQueryable(this, "refreshSession"));
}
}
export interface IWorkbookWithSession extends _WorkbookWithSession {}
export const WorkbookWithSession = graphInvokableFactory<IWorkbookWithSession>(_WorkbookWithSession);

@updateable()
@deleteable()
export class _Table extends _GraphInstance<WorkbookTableType> {
public get rows(): ITableRows {
return TableRows(this);
}
public get columns(): ITableColumns {
return TableColumns(this);
}
}
export interface ITable extends _Table, IUpdateable, IDeleteable {}
export const Table = graphInvokableFactory<ITable>(_Table);

@defaultPath("tables")
@addable()
@getById(Table)
export class _Tables extends _GraphCollection<WorkbookTableType[]> {
public getByName(name: string): ITable {
return Table(this, name);
}
}
export interface ITables extends _Tables, IAddable, IGetById<ITable> {}
export const Tables = graphInvokableFactory<ITables>(_Tables);

@deleteable()
@updateable()
export class _TableRow extends _GraphInstance<WorkbookTableRowType> {

}
export interface ITableRow extends _TableRow, IUpdateable, IDeleteable {}
export const TableRow = graphInvokableFactory<ITableRow>(_TableRow);

@defaultPath("rows")
@addable()
export class _TableRows extends _GraphCollection<WorkbookTableRowType[]> {
public getByIndex(index: number): ITableRow {
return TableRow(this, `${index}`);
}
}
export interface ITableRows extends _TableRows, IAddable {}
export const TableRows = graphInvokableFactory<ITableRows>(_TableRows);

@deleteable()
@updateable()
export class _TableColumn extends _GraphInstance<WorkbookTableColumnType> {

}
export interface ITableColumn extends _TableColumn, IUpdateable, IDeleteable {}
export const TableColumn = graphInvokableFactory<ITableColumn>(_TableColumn);

@defaultPath("columns")
@addable()
@getById(TableColumn)
export class _TableColumns extends _GraphCollection<WorkbookTableColumnType[]> {
public getByName(name: string): ITableColumn {
return TableColumn(this, name);
}
}
export interface ITableColumns extends _TableColumns, IAddable {}
export const TableColumns = graphInvokableFactory<ITableColumns>(_TableColumns);