diff options
| author | Ryan Dahl <ry@tinyclouds.org> | 2021-08-11 12:27:05 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-11 12:27:05 +0200 |
| commit | a0285e2eb88f6254f6494b0ecd1878db3a3b2a58 (patch) | |
| tree | 90671b004537e20f9493fd3277ffd21d30b39a0e /extensions/webstorage | |
| parent | 3a6994115176781b3a93d70794b1b81bc95e42b4 (diff) | |
Rename extensions/ directory to ext/ (#11643)
Diffstat (limited to 'extensions/webstorage')
| -rw-r--r-- | extensions/webstorage/01_webstorage.js | 191 | ||||
| -rw-r--r-- | extensions/webstorage/Cargo.toml | 20 | ||||
| -rw-r--r-- | extensions/webstorage/README.md | 5 | ||||
| -rw-r--r-- | extensions/webstorage/lib.deno_webstorage.d.ts | 42 | ||||
| -rw-r--r-- | extensions/webstorage/lib.rs | 245 |
5 files changed, 0 insertions, 503 deletions
diff --git a/extensions/webstorage/01_webstorage.js b/extensions/webstorage/01_webstorage.js deleted file mode 100644 index 558522a3c..000000000 --- a/extensions/webstorage/01_webstorage.js +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -/// <reference path="../../core/internal.d.ts" /> - -((window) => { - const core = window.Deno.core; - const webidl = window.__bootstrap.webidl; - const { - Symbol, - SymbolFor, - ObjectDefineProperty, - ObjectFromEntries, - ObjectEntries, - ReflectGet, - Proxy, - } = window.__bootstrap.primordials; - - const _persistent = Symbol("[[persistent]]"); - - class Storage { - [_persistent]; - - constructor() { - webidl.illegalConstructor(); - } - - get length() { - webidl.assertBranded(this, Storage); - return core.opSync("op_webstorage_length", this[_persistent]); - } - - key(index) { - webidl.assertBranded(this, Storage); - const prefix = "Failed to execute 'key' on 'Storage'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - index = webidl.converters["unsigned long"](index, { - prefix, - context: "Argument 1", - }); - - return core.opSync("op_webstorage_key", index, this[_persistent]); - } - - setItem(key, value) { - webidl.assertBranded(this, Storage); - const prefix = "Failed to execute 'setItem' on 'Storage'"; - webidl.requiredArguments(arguments.length, 2, { prefix }); - key = webidl.converters.DOMString(key, { - prefix, - context: "Argument 1", - }); - value = webidl.converters.DOMString(value, { - prefix, - context: "Argument 2", - }); - - core.opSync("op_webstorage_set", { - keyName: key, - keyValue: value, - }, this[_persistent]); - } - - getItem(key) { - webidl.assertBranded(this, Storage); - const prefix = "Failed to execute 'getItem' on 'Storage'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - key = webidl.converters.DOMString(key, { - prefix, - context: "Argument 1", - }); - - return core.opSync("op_webstorage_get", key, this[_persistent]); - } - - removeItem(key) { - webidl.assertBranded(this, Storage); - const prefix = "Failed to execute 'removeItem' on 'Storage'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - key = webidl.converters.DOMString(key, { - prefix, - context: "Argument 1", - }); - - core.opSync("op_webstorage_remove", key, this[_persistent]); - } - - clear() { - webidl.assertBranded(this, Storage); - core.opSync("op_webstorage_clear", this[_persistent]); - } - } - - function createStorage(persistent) { - if (persistent) window.location; - - const storage = webidl.createBranded(Storage); - storage[_persistent] = persistent; - - const proxy = new Proxy(storage, { - deleteProperty(target, key) { - if (typeof key == "symbol") { - delete target[key]; - } else { - target.removeItem(key); - } - return true; - }, - defineProperty(target, key, descriptor) { - if (typeof key == "symbol") { - ObjectDefineProperty(target, key, descriptor); - } else { - target.setItem(key, descriptor.value); - } - return true; - }, - get(target, key) { - if (typeof key == "symbol") return target[key]; - if (key in target) { - return ReflectGet(...arguments); - } else { - return target.getItem(key) ?? undefined; - } - }, - set(target, key, value) { - if (typeof key == "symbol") { - ObjectDefineProperty(target, key, { - value, - configurable: true, - }); - } else { - target.setItem(key, value); - } - return true; - }, - has(target, p) { - return (typeof target.getItem(p)) === "string"; - }, - ownKeys() { - return core.opSync("op_webstorage_iterate_keys", persistent); - }, - getOwnPropertyDescriptor(target, key) { - if (arguments.length === 1) { - return undefined; - } - if (key in target) { - return undefined; - } - const value = target.getItem(key); - if (value === null) { - return undefined; - } - return { - value, - enumerable: true, - configurable: true, - writable: true, - }; - }, - }); - - proxy[SymbolFor("Deno.customInspect")] = function (inspect) { - return `${this.constructor.name} ${ - inspect({ - length: this.length, - ...ObjectFromEntries(ObjectEntries(proxy)), - }) - }`; - }; - - return proxy; - } - - let localStorage; - let sessionStorage; - - window.__bootstrap.webStorage = { - localStorage() { - if (!localStorage) { - localStorage = createStorage(true); - } - return localStorage; - }, - sessionStorage() { - if (!sessionStorage) { - sessionStorage = createStorage(false); - } - return sessionStorage; - }, - Storage, - }; -})(this); diff --git a/extensions/webstorage/Cargo.toml b/extensions/webstorage/Cargo.toml deleted file mode 100644 index 492a69bc1..000000000 --- a/extensions/webstorage/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -[package] -name = "deno_webstorage" -version = "0.9.0" -authors = ["the Deno authors"] -edition = "2018" -license = "MIT" -readme = "README.md" -repository = "https://github.com/denoland/deno" -description = "Implementation of WebStorage API for Deno" - -[lib] -path = "lib.rs" - -[dependencies] -deno_core = { version = "0.96.0", path = "../../core" } -deno_web = { version = "0.45.0", path = "../web" } -rusqlite = { version = "0.25.3", features = ["unlock_notify", "bundled"] } -serde = { version = "1.0.126", features = ["derive"] } diff --git a/extensions/webstorage/README.md b/extensions/webstorage/README.md deleted file mode 100644 index a0f8a0613..000000000 --- a/extensions/webstorage/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# deno_webstorage - -This op crate implements the WebStorage spec in Deno. - -Spec: https://html.spec.whatwg.org/multipage/webstorage.html diff --git a/extensions/webstorage/lib.deno_webstorage.d.ts b/extensions/webstorage/lib.deno_webstorage.d.ts deleted file mode 100644 index bf438e005..000000000 --- a/extensions/webstorage/lib.deno_webstorage.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -// deno-lint-ignore-file no-explicit-any - -/// <reference no-default-lib="true" /> -/// <reference lib="esnext" /> - -/** This Web Storage API interface provides access to a particular domain's session or local storage. It allows, for example, the addition, modification, or deletion of stored data items. */ -interface Storage { - /** - * Returns the number of key/value pairs currently present in the list associated with the object. - */ - readonly length: number; - /** - * Empties the list associated with the object of all key/value pairs, if there are any. - */ - clear(): void; - /** - * Returns the current value associated with the given key, or null if the given key does not exist in the list associated with the object. - */ - getItem(key: string): string | null; - /** - * Returns the name of the nth key in the list, or null if n is greater than or equal to the number of key/value pairs in the object. - */ - key(index: number): string | null; - /** - * Removes the key/value pair with the given key from the list associated with the object, if a key/value pair with the given key exists. - */ - removeItem(key: string): void; - /** - * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously. - * - * Throws a "QuotaExceededError" DOMException exception if the new value couldn't be set. (Setting could fail if, e.g., the user has disabled storage for the site, or if the quota has been exceeded.) - */ - setItem(key: string, value: string): void; - [name: string]: any; -} - -declare var Storage: { - prototype: Storage; - new (): Storage; -}; diff --git a/extensions/webstorage/lib.rs b/extensions/webstorage/lib.rs deleted file mode 100644 index 6bf7e6818..000000000 --- a/extensions/webstorage/lib.rs +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::include_js_files; -use deno_core::op_sync; -use deno_core::Extension; -use deno_core::OpState; -use rusqlite::params; -use rusqlite::Connection; -use rusqlite::OptionalExtension; -use serde::Deserialize; -use std::fmt; -use std::path::PathBuf; - -#[derive(Clone)] -struct OriginStorageDir(PathBuf); - -const MAX_STORAGE_BYTES: u32 = 10 * 1024 * 1024; - -pub fn init(origin_storage_dir: Option<PathBuf>) -> Extension { - Extension::builder() - .js(include_js_files!( - prefix "deno:extensions/webstorage", - "01_webstorage.js", - )) - .ops(vec![ - ("op_webstorage_length", op_sync(op_webstorage_length)), - ("op_webstorage_key", op_sync(op_webstorage_key)), - ("op_webstorage_set", op_sync(op_webstorage_set)), - ("op_webstorage_get", op_sync(op_webstorage_get)), - ("op_webstorage_remove", op_sync(op_webstorage_remove)), - ("op_webstorage_clear", op_sync(op_webstorage_clear)), - ( - "op_webstorage_iterate_keys", - op_sync(op_webstorage_iterate_keys), - ), - ]) - .state(move |state| { - if let Some(origin_storage_dir) = origin_storage_dir.clone() { - state.put(OriginStorageDir(origin_storage_dir)); - } - Ok(()) - }) - .build() -} - -pub fn get_declaration() -> PathBuf { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_webstorage.d.ts") -} - -struct LocalStorage(Connection); -struct SessionStorage(Connection); - -fn get_webstorage( - state: &mut OpState, - persistent: bool, -) -> Result<&Connection, AnyError> { - let conn = if persistent { - if state.try_borrow::<LocalStorage>().is_none() { - let path = state.try_borrow::<OriginStorageDir>().ok_or_else(|| { - DomExceptionNotSupportedError::new( - "LocalStorage is not supported in this context.", - ) - })?; - std::fs::create_dir_all(&path.0)?; - let conn = Connection::open(path.0.join("local_storage"))?; - conn.execute( - "CREATE TABLE IF NOT EXISTS data (key VARCHAR UNIQUE, value VARCHAR)", - params![], - )?; - - state.put(LocalStorage(conn)); - } - - &state.borrow::<LocalStorage>().0 - } else { - if state.try_borrow::<SessionStorage>().is_none() { - let conn = Connection::open_in_memory()?; - conn.execute( - "CREATE TABLE data (key VARCHAR UNIQUE, value VARCHAR)", - params![], - )?; - - state.put(SessionStorage(conn)); - } - - &state.borrow::<SessionStorage>().0 - }; - - Ok(conn) -} - -pub fn op_webstorage_length( - state: &mut OpState, - persistent: bool, - _: (), -) -> Result<u32, AnyError> { - let conn = get_webstorage(state, persistent)?; - - let mut stmt = conn.prepare("SELECT COUNT(*) FROM data")?; - - let length: u32 = stmt.query_row(params![], |row| row.get(0))?; - - Ok(length) -} - -pub fn op_webstorage_key( - state: &mut OpState, - index: u32, - persistent: bool, -) -> Result<Option<String>, AnyError> { - let conn = get_webstorage(state, persistent)?; - - let mut stmt = conn.prepare("SELECT key FROM data LIMIT 1 OFFSET ?")?; - - let key: Option<String> = stmt - .query_row(params![index], |row| row.get(0)) - .optional()?; - - Ok(key) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SetArgs { - key_name: String, - key_value: String, -} - -pub fn op_webstorage_set( - state: &mut OpState, - args: SetArgs, - persistent: bool, -) -> Result<(), AnyError> { - let conn = get_webstorage(state, persistent)?; - - let mut stmt = - conn.prepare("SELECT SUM(pgsize) FROM dbstat WHERE name = 'data'")?; - let size: u32 = stmt.query_row(params![], |row| row.get(0))?; - - if size >= MAX_STORAGE_BYTES { - return Err( - deno_web::DomExceptionQuotaExceededError::new( - "Exceeded maximum storage size", - ) - .into(), - ); - } - - conn.execute( - "INSERT OR REPLACE INTO data (key, value) VALUES (?, ?)", - params![args.key_name, args.key_value], - )?; - - Ok(()) -} - -pub fn op_webstorage_get( - state: &mut OpState, - key_name: String, - persistent: bool, -) -> Result<Option<String>, AnyError> { - let conn = get_webstorage(state, persistent)?; - - let mut stmt = conn.prepare("SELECT value FROM data WHERE key = ?")?; - - let val = stmt - .query_row(params![key_name], |row| row.get(0)) - .optional()?; - - Ok(val) -} - -pub fn op_webstorage_remove( - state: &mut OpState, - key_name: String, - persistent: bool, -) -> Result<(), AnyError> { - let conn = get_webstorage(state, persistent)?; - - conn.execute("DELETE FROM data WHERE key = ?", params![key_name])?; - - Ok(()) -} - -pub fn op_webstorage_clear( - state: &mut OpState, - persistent: bool, - _: (), -) -> Result<(), AnyError> { - let conn = get_webstorage(state, persistent)?; - - conn.execute("DROP TABLE data", params![])?; - conn.execute( - "CREATE TABLE data (key VARCHAR UNIQUE, value VARCHAR)", - params![], - )?; - - Ok(()) -} - -pub fn op_webstorage_iterate_keys( - state: &mut OpState, - persistent: bool, - _: (), -) -> Result<Vec<String>, AnyError> { - let conn = get_webstorage(state, persistent)?; - - let mut stmt = conn.prepare("SELECT key FROM data")?; - - let keys = stmt - .query_map(params![], |row| row.get::<_, String>(0))? - .map(|r| r.unwrap()) - .collect(); - - Ok(keys) -} - -#[derive(Debug)] -pub struct DomExceptionNotSupportedError { - pub msg: String, -} - -impl DomExceptionNotSupportedError { - pub fn new(msg: &str) -> Self { - DomExceptionNotSupportedError { - msg: msg.to_string(), - } - } -} - -impl fmt::Display for DomExceptionNotSupportedError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad(&self.msg) - } -} - -impl std::error::Error for DomExceptionNotSupportedError {} - -pub fn get_not_supported_error_class_name( - e: &AnyError, -) -> Option<&'static str> { - e.downcast_ref::<DomExceptionNotSupportedError>() - .map(|_| "DOMExceptionNotSupportedError") -} |
