Comparing version 0.0.1-alpha.5 to 0.0.1-alpha.6
@@ -15,3 +15,3 @@ import Coda from "../coda.js"; | ||
let rows = (await this.request(`docs/${file.docId}/tables/${file.tableId}/rows/?valueFormat=rich&useColumnNames=true&sortBy=natural`))?.items; | ||
let rows = await this.getTableRows(file); | ||
@@ -81,2 +81,20 @@ // Transform rows to a more usable format | ||
async getTableRows (file = this.file) { | ||
let items = []; | ||
let options = {valueFormat: "rich", useColumnNames: true, sortBy: "natural"}; | ||
let optionsString = Object.entries(options).map(([key, value]) => `${key}=${value}`).join("&"); | ||
let data; | ||
let url = `docs/${file.docId}/tables/${file.tableId}/rows/?${optionsString}`; | ||
do { | ||
data = await this.request(url + (data?.nextPageToken ? `&pageToken=${data.nextPageToken}` : "")); | ||
if (data) { | ||
items.push(...data.items); | ||
options.pageToken = data.nextPageToken; | ||
} | ||
} while (data?.nextPageToken); | ||
return items; | ||
} | ||
static parseURL (source) { | ||
@@ -83,0 +101,0 @@ let url = new URL(source); |
@@ -6,6 +6,8 @@ /** | ||
import OAuthBackend from "../../src/oauth-backend.js"; | ||
import hooks from "../../src/hooks.js"; | ||
import {readFile} from "../../src/util.js"; | ||
export default class Dropbox extends OAuthBackend { | ||
static apiDomain = "https://api.dropboxapi.com/2/"; | ||
static oAuth = "https://www.dropbox.com/oauth2/authorize"; | ||
static fileBased = true; | ||
constructor (url, o) { | ||
@@ -85,5 +87,2 @@ super(url, o); | ||
static apiDomain = "https://api.dropboxapi.com/2/" | ||
static oAuth = "https://www.dropbox.com/oauth2/authorize" | ||
static test (url) { | ||
@@ -98,3 +97,3 @@ url = new URL(url, location); | ||
return {url}; | ||
return {url}; | ||
} | ||
@@ -101,0 +100,0 @@ |
@@ -10,2 +10,4 @@ /** | ||
export default class GithubFile extends Github { | ||
static fileBased = true; | ||
/** | ||
@@ -86,3 +88,3 @@ * Low-level method to fetch a file from GitHub | ||
async put (data, {file, isEncoded} = {}) { | ||
const serialized = await this.stringify(data); | ||
const serialized = await this.stringify(data, {file}); | ||
return this.#write("put", file, serialized, {isEncoded}); | ||
@@ -89,0 +91,0 @@ } |
@@ -51,3 +51,3 @@ /** | ||
async put (data, {file = this.file, path} = {}) { | ||
async put (data, {file = this.file} = {}) { | ||
let call = "gists"; | ||
@@ -70,3 +70,3 @@ let gistId = file.gistId; | ||
[file.path]: { | ||
content: await this.stringify(data) | ||
content: await this.stringify(data, {file}) | ||
} | ||
@@ -73,0 +73,0 @@ }, |
@@ -8,2 +8,6 @@ /** | ||
export default class GoogleDrive extends Google { | ||
static apiDomain = "https://www.googleapis.com/"; | ||
static scopes = ["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"]; | ||
static fileBased = true; | ||
update (url, o = {}) { | ||
@@ -64,3 +68,3 @@ super.update(url, o); | ||
async put (data, {file} = {}) { | ||
const serialized = await this.stringify(data); | ||
const serialized = await this.stringify(data, {file}); | ||
let fileInfo; | ||
@@ -268,5 +272,2 @@ | ||
static apiDomain = "https://www.googleapis.com/"; | ||
static scopes = ["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"]; | ||
static test (url) { | ||
@@ -273,0 +274,0 @@ url = new URL(url); |
{ | ||
"name": "madata", | ||
"version": "0.0.1-alpha.5", | ||
"version": "0.0.1-alpha.6", | ||
"description": "", | ||
@@ -42,3 +42,4 @@ "main": "js/index.js", | ||
"postcss-cli": "^9.0.1", | ||
"postcss-nesting": "^12.0.1" | ||
"postcss-nesting": "^12.0.1", | ||
"release-it": "^16.2.1" | ||
}, | ||
@@ -45,0 +46,0 @@ "dependencies": { |
@@ -6,2 +6,3 @@ /** | ||
*/ | ||
import Format from './format.js'; | ||
import hooks from './hooks.js'; | ||
@@ -51,18 +52,61 @@ import { toArray, phrase, type } from './util.js'; | ||
async parse (data) { | ||
async parse (data, { file } = {}) { | ||
if (type(data) !== "string") { | ||
// Already parsed | ||
return data; | ||
} | ||
return this.options.format?.parse(data) ?? this.options.parse?.(data) ?? JSON.parse(data); | ||
if (type(this.options.parse) === "function") { | ||
// parse should take precedence over format | ||
return this.options.parse(data); | ||
} | ||
return this.#getFormat(file).parse(data); | ||
} | ||
async stringify (data) { | ||
async stringify (data, { file } = {}) { | ||
if (type(data) === "string") { | ||
// Already stringified | ||
return data; | ||
} | ||
return this.options.format?.stringify(data) ?? this.options.stringify?.(data) ?? JSON.stringify(data, null, "\t"); | ||
if (type(this.options.stringify) === "function") { | ||
// stringify should take precedence over format | ||
return this.options.stringify(data); | ||
} | ||
return this.#getFormat(file).stringify(data); | ||
} | ||
#getFormat (file) { | ||
let format = this.options.format; | ||
if (!format && this.constructor.fileBased && file) { | ||
// If file-based, try to match the filename first | ||
let extension = (file.filename ?? file.path ?? file.url).match(/\.(\w+)$/)?.[1]; | ||
if (extension) { | ||
format = Format.find({extension}); | ||
} | ||
} | ||
format ??= this.constructor.defaultFormat; | ||
if (format && typeof format === "string") { | ||
format = Format.find(format); | ||
if (!format) { | ||
throw new Error(`No format found for "${this.options.format}"`); | ||
} | ||
if (this.options.format) { | ||
this.options.format = format; | ||
} | ||
else { | ||
this.constructor.defaultFormat = format; | ||
} | ||
} | ||
return format; | ||
} | ||
updatePermissions(o) { | ||
@@ -150,3 +194,3 @@ let changed = []; | ||
this.rawData = response; | ||
this.data = this.parse(response); | ||
this.data = await this.parse(response, { file }); | ||
} | ||
@@ -296,3 +340,4 @@ | ||
static hooks = hooks | ||
static hooks = hooks; | ||
static defaultFormat = "JSON"; | ||
@@ -307,3 +352,3 @@ static phrase (id, ...args) { | ||
*/ | ||
static authProvider = "https://auth.madata.dev" | ||
static authProvider = "https://auth.madata.dev"; | ||
@@ -310,0 +355,0 @@ /** |
@@ -58,4 +58,5 @@ export default class Format { | ||
/** | ||
* Find a registered Format by its MIME type or extension | ||
* @param {object} criteria | ||
* Find a registered Format by its name, MIME type, or extension | ||
* @param {string | object} criteria If string, searches by name, MIME type, or extension, prioritizing name matches. | ||
* If object, searches by the specific criteria provided. | ||
* @param {string} [criteria.mimeType] | ||
@@ -65,3 +66,17 @@ * @param {string} [criteria.extension] | ||
*/ | ||
static find ({ mimeType, extension }) { | ||
static find (criteria) { | ||
if (typeof criteria === "string") { | ||
// Find format by either id, extension, or MIME type, prioritizing id | ||
// Case insensitive, though name lookup is O(1) if you use the correct case | ||
if (this[criteria]) { | ||
return this[criteria]; | ||
} | ||
return this.all.find(format => format.name.toLowerCase() === criteria.toLowerCase()) | ||
?? this.find({ extension: criteria }) | ||
?? this.find({ mimeType: criteria }) ?? null; | ||
} | ||
let { mimeType, extension } = criteria; | ||
return this.all.find(format => { | ||
@@ -68,0 +83,0 @@ return (mimeType && format.mimeTypes.includes(mimeType)) || |
@@ -250,3 +250,3 @@ /** | ||
addEventListener("message", evt => { | ||
if (evt.source === this.authPopup) { | ||
if (evt.source === this.authPopup && evt.data.backend) { | ||
if (evt.data.backend == oAuthBackend.name) { | ||
@@ -253,0 +253,0 @@ resolve(evt.data.token); |
Sorry, the diff of this file is not supported yet
3063949
66749
10