OneDrive and SharePoint document libraries over the Microsoft Graph
driveItem API. The same functions work for OneDrive (personal),
OneDrive for work or school, and SharePoint document libraries:
every drive is addressed by its base path, and a library is just a
drive id. Credentials, clouds, retries and errors come from
microsoft-graph.
Namespaces
::microsoft::onedrive::drives- resolve drives (me, user, site, group, id)::microsoft::onedrive::items- get, list, search, folders, rename, move, copy, delete::microsoft::onedrive::content-read-document, downloads, Range, PDF/HTML conversion, thumbnails::microsoft::onedrive::upload- simple uploads and resumable upload sessions::microsoft::onedrive::sharing- sharing links, invitations, permissions, app grants::microsoft::onedrive::versions- version history::microsoft::onedrive::delta- delta sync and change-notification subscriptions
Choosing the drive. Every function takes opts.drive: "me"
(the default for delegated tokens), a drive id (a SharePoint library
from ::microsoft::sharepoint::sites/list-drives), or a base path
from user-drive, site-drive, group-drive. The
microsoft.onedrive.drive-id context variable sets a default drive
(needed for app-only tokens, which have no /me).
Addressing items. An item is an id ("01ABCDEF..."), "root",
a path from the drive root ("/Reports/Q3.xlsx", encoded for you),
or a driveItem / DocFile Map (its own drive is used, so items from
delta, search and shared lists work across drives).
Quick start
::items ::microsoft::onedrive::items
::content ::microsoft::onedrive::content
files ::items/list-all-children("/Reports", {}, 50)
doc ::content/read-document(first(files), "auto")
doc.file.name
doc.bytes
Values
CONFLICT_BEHAVIORS
CONFLICT_BEHAVIORS: Vec [
"fail",
"replace",
"rename"
]
HTML_SOURCE_EXTENSIONS
HTML_SOURCE_EXTENSIONS: Vec [
"loop",
"fluid",
"wbtx",
"whiteboard"
]
LOCAL_KEYS
LOCAL_KEYS: Vec [
"drive",
"conflict",
"if-match",
"range",
"chunk-size",
"fallback",
"offset",
"description",
"defer-commit",
"file-size"
]
MAX_CONVERT_BYTES
MAX_CONVERT_BYTES: Int 2097152
PDF_SOURCE_EXTENSIONS
PDF_SOURCE_EXTENSIONS: Vec [
"doc",
"docx",
"dot",
"dotx",
"dotm",
"dsn",
"dwg",
"eml",
"epub",
"fluidframework",
"form",
"htm",
"html",
"loop",
"loot",
"markdown",
"md",
"msg",
"note",
"odp",
"ods",
"odt",
"page",
"pps",
"ppsx",
"ppt",
"pptx",
"pulse",
"rtf",
"task",
"tif",
"tiff",
"wbtx",
"whiteboard",
"xls",
"xlsm",
"xlsx"
]
PROVIDER
PROVIDER: Str "microsoft-onedrive"
TEXT_EXTENSIONS
TEXT_EXTENSIONS: Vec [
"txt",
"text",
"md",
"markdown",
"csv",
"tsv",
"json",
"jsonl",
"ndjson",
"xml",
"yaml",
"yml",
"html",
"htm",
"log",
"ini",
"toml",
"sql",
"svg",
"rtf"
]
Functions
base-mime
fn (content-type: Str?): Str?
A Content-Type without parameters, lower-cased: "text/plain; charset=utf-8" becomes "text/plain" (pure).
child-path
fn (parent: Any, name: Str, opts: Map): Str
The Graph path of a (possibly new) child named name under parent
(pure), for uploads: {drive}/root:/name:, {drive}/root:/parent/path/name:
or {drive}/items/{parent-id}:/name:.
conflict-behavior
fn (value: Any, default: Str?): Str?
Validate a conflict behavior (fail, replace, rename); null passes through as default (pure).
content-from-bytes
fn (file-id: Str, bytes: Bytes, mime-type: Str?, name: Str?, source: Str): FileContent
Build a FileContent from raw bytes, their MIME type, the file name (for text detection) and the source (pure).
content-from-response
fn (file-id: Str, response: Map, name: Str?, source: Str): FileContent
Build a FileContent from an HTTP response: response-bytes and the Content-Type header (pure).
content-text
fn (content: Map): Str
The text of a FileContent: its text, or the UTF-8 decoding of bytes (invalid sequences become U+FFFD).
conversion-formats
fn (name: Str?): Vec
The MIME types Graph can convert a file with this name to (pure): application/pdf and/or text/html, from the documented source extensions.
create-folder of ::microsoft::onedrive::items/create-folder
fn (parent: Any, name: Str): Map
fn (parent: Any, name: Str, opts: Map): Map
POST {parent}/children - create a folder. opts.conflict is
"fail" (default), "rename" or "replace". Returns the folder.
folder ::microsoft::onedrive::items/create-folder("root", "Reports", {conflict: "rename"})
creds
fn (opts: Map): Map
The microsoft-graph part of opts (credentials, cloud, retry, headers), passed through to ::microsoft::graph::api.
delete-item of ::microsoft::onedrive::items/delete-item
fn (item: Any): Bool
fn (item: Any, opts: Map): Bool
DELETE an item: it moves to the recycle bin (restorable for 93 days on work/school, 30 days on personal). opts.if-match (eTag) makes it conditional. Returns true.
download of ::microsoft::onedrive::content/download
fn (item: Any): ::microsoft::onedrive/FileContent
fn (item: Any, opts: Map): ::microsoft::onedrive/FileContent
GET {item}/content - download a file's exact bytes as a FileContent
(Hot follows Graph's 302 to the pre-authenticated URL). When the file
is larger than http.max-response-bytes, it is fetched again in Range
chunks (download-chunked). Shared items (remoteItem) are read from
the owner's drive. opts.range: {start, end} downloads a slice.
pdf ::microsoft::onedrive::content/download("/Contracts/MSA.pdf")
pdf.mime-type // "application/pdf"
pdf.bytes
drive
fn (drive-id: Str): Str
A drive by id (any OneDrive or SharePoint library): /drives/{id}.
drive-base
fn (opts: Map): Str
The base path of the drive a call targets: opts.drive, else the microsoft.onedrive.drive-id context variable, else /me/drive.
microsoft.onedrive.drive-id
drive-base-from
fn (ref: Any, default-drive-id: Any): Str
The base path for a drive reference (pure): null means default
(from context) or /me/drive; "me" is /me/drive; a Str starting
with / is a base path as built by drive, user-drive,
site-drive, group-drive; any other Str is a drive id; a Map may
carry drive-id, user, site or group.
encode-path
fn (path: Str): Str
Encode a drive path for path-based addressing (pure): segments are
split on /, empty ones dropped, and each is percent-encoded (spaces,
#, %, ?, &, ' and non-ASCII included), with a leading /.
::microsoft::onedrive/encode-path("/Shared Docs/Q3 #1.docx")
// "/Shared%20Docs/Q3%20%231.docx"
extension
fn (name: Str?): Str
The lower-case extension of a file name without the dot ("Q3 Plan.DOCX" is "docx"), or "" (pure).
follow-redirect
fn (response: Result): Any
If response is a 3xx with a Location (Graph's /content and
?format= answers point at a pre-authenticated URL), GET that URL
without an Authorization header and return its response; otherwise
return response unchanged. Hot's client normally follows the
redirect itself; this covers a runtime that hands the 302 back.
get-item of ::microsoft::onedrive::items/get-item
fn (item: Any): Map
fn (item: Any, opts: Map): Map
GET an item by id, /path, "root" or Map. opts takes select,
expand (e.g. "thumbnails", "permissions") and drive.
item ::microsoft::onedrive::items/get-item("/Reports/Q3.xlsx")
item.id
item.file.hashes.quickXorHash
group-drive
fn (group-id: Str): Str
A Microsoft 365 group's (or team's) document library: /groups/{id}/drive.
if-match-headers
fn (opts: Map): Map
is-folder-item
fn (item: Map): Bool
True for a folder (or a shared folder via remoteItem.folder) or a package (OneNote notebook), which have no content to download (pure).
is-path-ref
fn (ref: Any): Bool
is-root-path
fn (ref: Any): Bool
is-textual
fn (mime-type: Str?, name: Str?): Bool
True when a file is text by MIME type, or by extension (.txt, .md, .csv, .json, ... since OneDrive often stores those as application/octet-stream) (pure).
is-textual-mime
fn (mime-type: Str?): Bool
True when content of this MIME type is text: text/*, JSON, XML, YAML, SQL, SVG, +json / +xml (pure).
item-drive-id
fn (item: Map): Str?
The drive id a driveItem or DocFile Map belongs to (parentReference.driveId or drive-id), or null (pure).
item-path
fn (ref: Any, opts: Map): Str
The Graph path of an item reference (pure): "root" and "/" are
{drive}/root; a /path is {drive}/root:/encoded/path:; a Str id
is {drive}/items/{id}; a Map uses its own id and drive
(/drives/{driveId}/items/{id}), falling back to opts.drive.
Append /children, /content, ... to the result.
::microsoft::onedrive/item-path("/Reports/Q3.xlsx", {})
// "/me/drive/root:/Reports/Q3.xlsx:"
::microsoft::onedrive/item-path("01ABC", {drive: "b!xyz"})
// "/drives/b%21xyz/items/01ABC"
list-all-children of ::microsoft::onedrive::items/list-all-children
fn (folder: Any): Vec
fn (folder: Any, opts: Map): Vec
fn (folder: Any, opts: Map, limit: Int?): Vec
Follow @odata.nextLink and return every child of folder (a Vec of
driveItems), or at most limit. Uses top: 200 unless set.
files filter(::microsoft::onedrive::items/list-all-children("root", {}, 1000), (i) { is-map(i.file) })
list-children of ::microsoft::onedrive::items/list-children
fn (folder: Any): Map
fn (folder: Any, opts: Map): Map
GET {folder}/children - one page of a folder's children: Graph's
{value, @odata.nextLink?}. Follow @odata.nextLink with
::microsoft::graph::api/fetch-page or use list-all-children.
opts takes select, expand, top (page size), orderby (e.g.
"name", "lastModifiedDateTime desc"; not on every drive type) and
drive.
me-drive
fn (): Str
The signed-in user's OneDrive: "/me/drive" (delegated tokens only).
query-opts
fn (defaults: Map, opts: Map): Map
fn (defaults: Map, opts: Map, extra-local: Vec): Map
The OData/API parameters of opts (pure): defaults, overridden by opts minus credential keys, this package's local keys and extra-local, nulls dropped. Pass a key as null in opts to drop a default.
read-document of ::microsoft::onedrive::content/read-document
fn (item: Any): ::microsoft::onedrive/FileContent
fn (item: Any, format: Str?): ::microsoft::onedrive/FileContent
fn (item: Any, format: Str?, opts: Map): ::microsoft::onedrive/FileContent
Read any file as a FileContent with its DocFile attached, for RAG
ingestion and file-triggered workflows. Shared items are followed to
the owner's drive; folders return an Err. See read-plan for the
formats:
"auto"(default) /"original"- the stored bytes: Office files as-is for a text extractor (hot.dev/libreoffice,pandoc, ...),textset for.txt/.md/.csv/.jsonand other text"pdf"- a PDF: converted by Graph when the file is convertible and at most 2 MB, otherwise (or when conversion fails) the original"html"- Loop / Whiteboard as HTML, otherwise the original"text"- text files only; an Err for binaries
format on the result says what you got (original, pdf, html
or text); check mime-type too.
doc ::microsoft::onedrive::content/read-document("/Specs/Design.docx", "pdf")
doc.format // "pdf" (or "original" when the docx was over 2 MB)
doc.file.version // eTag, for incremental re-indexing
remote-target
fn (item: Map): Map
For a shared or "Add to My files" item (a remoteItem facet), a Map addressing the target item in its own drive; otherwise item itself (pure).
response-bytes
fn (response: Map): Bytes
The exact body of an HTTP response as Bytes: body-bytes, never the auto-decoded body (so a JSON file stays bytes) (pure).
search of ::microsoft::onedrive::items/search
fn (query: Str): Vec
fn (query: Str, opts: Map): Vec
fn (query: Str, opts: Map, limit: Int?): Vec
Search a drive for query (file names, metadata and content), all
pages or at most limit. Defaults to {drive}/root/search(...);
opts.folder searches under one folder, and opts.scope: "drive"
uses {drive}/search(...), which on /me/drive also includes items
shared with the user. opts also takes select, top.
hits ::microsoft::onedrive::items/search("quarterly report", {}, 25)
site-drive
fn (site-id: Str): Str
A SharePoint site's default document library: /sites/{site-id}/drive.
sync-changes of ::microsoft::onedrive::delta/sync-changes
fn (delta-link: Str?): DeltaSet
fn (delta-link: Str?, opts: Map): DeltaSet
Read every delta page since delta-link (null: enumerate the whole
drive) and return a DeltaSet with the link to use next time. A
410 Gone restarts the enumeration from Graph's Location and
marks the set resync (see the namespace doc). opts takes drive,
select, top, prefer, max-pages (default 5000) and credentials.
::delta ::microsoft::onedrive::delta
set ::delta/sync-changes(saved-link)
upserts ::delta/changed-items(set) // DocFiles to (re)index
deletes ::delta/deleted-ids(set) // ids to drop
saved-link set.delta-link
to-doc-file
fn (item: Map): DocFile
Normalise a driveItem (from get-item, list-children, search,
delta, ...) into a DocFile (pure). Missing fields become
null/false; for a remoteItem the target's file facet and size fill
in what the local entry lacks.
f ::microsoft::onedrive/to-doc-file(item)
f.hashes.quickXorHash // change detection on OneDrive for work / SharePoint
to-doc-files
fn (items: Vec): Vec
to-doc-file over a Vec of driveItems.
upload-file of ::microsoft::onedrive::upload/upload-file
fn (parent: Any, name: Str, content: Any, mime-type: Str?): Map
fn (parent: Any, name: Str, content: Any, mime-type: Str?, opts: Map): Map
Upload content as name under parent (an id, "root", a /path
or a Map): a simple PUT up to 4 MiB, an upload session above (or with
opts.resumable: true). opts.conflict (replace default,
rename, fail), chunk-size, drive. Returns the driveItem.
item ::microsoft::onedrive::upload/upload-file("/Reports", "q3.csv", "region,total\nwest,42\n", "text/csv")
big ::microsoft::onedrive::upload/upload-file("root", "video.mp4", video-bytes, "video/mp4", {conflict: "rename"})
user-drive
fn (user: Str): Str
A user's OneDrive by id or user principal name: /users/{id}/drive.
Types
DocFile
DocFile type {
provider: Str,
id: Str,
name: Str,
mime-type: Str,
size: Int?,
modified: Str?,
created: Str?,
parents: Vec,
drive-id: Str?,
web-url: Str?,
version: Str?,
revision-id: Str?,
md5: Str?,
sha256: Str?,
hashes: Map,
is-folder: Bool,
is-google-native: Bool,
is-shortcut: Bool,
shortcut-target-id: Str?,
trashed: Bool,
export-formats: Vec,
raw: Map
}
Provider-neutral file metadata, with the same fields as
::google::drive/DocFile plus hashes, so a documents pipeline can
treat OneDrive, SharePoint and Google Drive alike.
Fields
provider-"microsoft-onedrive"(OneDrive and SharePoint libraries alike)id,name,mime-type(file.mimeType;""for folders and packages)size- bytes (Int); null for folders and packagesmodified,created-lastModifiedDateTime,createdDateTimeparents-[parentReference.id](driveItems have one parent)drive-id-parentReference.driveIdweb-url- the browser link (webUrl)version- theeTag(changes on any change; use for If-Match)revision-id- thecTag(changes only when content changes)md5- always null (Graph has no MD5)sha256-file.hashes.sha256Hashlower-cased when present (Graph documents it as unsupported; usually null)hashes-file.hashesas returned:quickXorHash(base64, OneDrive for work and SharePoint),sha1Hashandcrc32Hash(personal OneDrive)is-folder(folderfacet),is-google-native(always false),is-shortcut(aremoteItem: shared or "Add to My files"),shortcut-target-id(the remote item's id)trashed- true when the item has adeletedfacet (delta)export-formats- MIME types Graph can convert this file to (application/pdf,text/html)raw- the driveItem as returned
FileContent
FileContent type {
file-id: Str,
name: Str?,
mime-type: Str?,
size: Int,
bytes: Bytes,
text: Str?,
source: Str,
format: Str?,
file: DocFile?
}
Downloaded or converted file content (the same shape as
::google::drive/FileContent). bytes is always the exact response
body (binary safe); text is the UTF-8 decoding when the content is
textual (by MIME type or by extension), else null.
Fields
file-id,namemime-type- the MIME type ofbytessize-length(bytes)bytes,textsource-"download","range","chunked","convert","version"or"thumbnail"format- whatread-documentproduced:"original","pdf","html"or"text"; null otherwisefile- theDocFile(set byread-document)