fix(bundler): Fix bugs (#1437)

swc_bundler:
 - [x] Fix wrapped esms. (denoland/deno#9307)
 - [x] Make test secure.
This commit is contained in:
강동윤 2021-03-02 17:33:03 +09:00 committed by GitHub
parent eec65f25bb
commit bbaf619f63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1755 changed files with 264149 additions and 422 deletions

View File

@ -9,7 +9,7 @@ include = ["Cargo.toml", "build.rs", "src/**/*.rs", "src/**/*.js"]
license = "Apache-2.0/MIT"
name = "swc_bundler"
repository = "https://github.com/swc-project/swc.git"
version = "0.25.1"
version = "0.25.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]

5
bundler/scripts/download.sh Executable file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
export CI=1
cargo test --test fixture
cargo test --test deno

View File

@ -1,8 +1,6 @@
#!/usr/bin/env bash
set -eux
cargo test --no-run
cargo test --lib
cargo test --test fixture
(cd ../spack && cargo test --test fixture)

View File

@ -8,7 +8,7 @@ use swc_atoms::js_word;
use swc_common::{SyntaxContext, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_utils::{find_ids, private_ident, ExprFactory};
use swc_ecma_visit::{noop_fold_type, noop_visit_type, Fold, FoldWith, Node, Visit};
use swc_ecma_visit::{noop_fold_type, noop_visit_type, Fold, Node, Visit};
impl<L, R> Bundler<'_, L, R>
where
@ -35,7 +35,7 @@ where
&self,
ctx: &Ctx,
id: ModuleId,
mut module: Modules,
module: Modules,
) -> Result<Modules, Error> {
let span = DUMMY_SP;
let info = self.scope.get_module(id).unwrap();
@ -44,7 +44,6 @@ where
None => bail!("{:?} should not be wrapped with a function", id),
};
let injected_ctxt = self.injected_ctxt;
module.sort(id, &ctx.graph, &self.cm);
let is_async = {
let mut v = TopLevelAwaitFinder { found: false };
@ -52,93 +51,89 @@ where
v.found
};
let mut module_items = vec![];
let mut addtional_items = vec![];
let stmts = {
module.iter().for_each(|(_, item)| {
match item {
// Handle `export *`-s from dependency modules.
//
// See: https://github.com/denoland/deno/issues/9200
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport {
span,
ref specifiers,
..
})) if span.ctxt == injected_ctxt => {
for s in specifiers {
match s {
ExportSpecifier::Named(ExportNamedSpecifier {
orig,
exported: Some(exported),
..
}) => {
if let Some(..) = ctx.transitive_remap.get(&exported.span.ctxt)
{
let mut var_name = exported.clone();
var_name.span.ctxt = info.export_ctxt();
module_items.push(
exported
.clone()
.assign_to(var_name.clone())
.into_module_item(
injected_ctxt,
"export * in a wrapped esm",
),
);
let specifier =
ExportSpecifier::Named(ExportNamedSpecifier {
span: DUMMY_SP,
orig: orig.clone(),
exported: Some(exported.clone()),
});
module_items.push(ModuleItem::ModuleDecl(
ModuleDecl::ExportNamed(NamedExport {
module.iter().for_each(|(module_id, item)| {
match item {
// Handle `export *`-s from dependency modules.
//
// See: https://github.com/denoland/deno/issues/9200
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport {
span,
ref specifiers,
..
})) if span.ctxt == injected_ctxt => {
for s in specifiers {
match s {
ExportSpecifier::Named(ExportNamedSpecifier {
orig,
exported: Some(exported),
..
}) => {
if let Some(..) = ctx.transitive_remap.get(&exported.span.ctxt) {
let mut var_name = exported.clone();
var_name.span.ctxt = info.export_ctxt();
addtional_items.push((
module_id,
exported
.clone()
.assign_to(var_name.clone())
.into_module_item(
injected_ctxt,
"export * in a wrapped esm",
),
));
let specifier = ExportSpecifier::Named(ExportNamedSpecifier {
span: DUMMY_SP,
orig: orig.clone(),
exported: Some(exported.clone()),
});
addtional_items.push((
module_id,
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(
NamedExport {
span: DUMMY_SP.with_ctxt(injected_ctxt),
specifiers: vec![specifier],
src: None,
type_only: false,
asserts: None,
}),
));
}
},
)),
));
}
_ => {}
}
_ => {}
}
}
_ => {}
}
});
_ => {}
}
});
let mut module = Module::from(module).fold_with(&mut ExportToReturn {
synthesized_ctxt: self.synthesized_ctxt,
return_props: Default::default(),
});
take(&mut module.body)
.into_iter()
.filter_map(|v| match v {
ModuleItem::Stmt(s @ Stmt::Return(..)) => Some(s),
ModuleItem::Stmt(s) => {
module_items.push(ModuleItem::Stmt(s));
None
}
ModuleItem::ModuleDecl(ModuleDecl::ExportAll(ref export)) => {
// We handle this later.
let mut map = ctx.export_stars_in_wrapped.lock();
map.entry(id).or_default().push(export.span.ctxt);
module_items.push(v);
None
}
_ => {
module_items.push(v);
None
}
})
.collect()
let mut export_visitor = ExportToReturn {
synthesized_ctxt: self.synthesized_ctxt,
return_props: Default::default(),
};
let mut module = module.fold_with(&mut export_visitor);
module.append_all(addtional_items);
let return_stmt = Stmt::Return(ReturnStmt {
span: DUMMY_SP,
arg: Some(Box::new(Expr::Object(ObjectLit {
span: DUMMY_SP,
props: take(&mut export_visitor.return_props),
}))),
});
module.iter().for_each(|(_, v)| match v {
ModuleItem::ModuleDecl(ModuleDecl::ExportAll(ref export)) => {
// We handle this later.
let mut map = ctx.export_stars_in_wrapped.lock();
map.entry(id).or_default().push(export.span.ctxt);
}
_ => {}
});
let module_fn = Expr::Fn(FnExpr {
function: Function {
@ -147,7 +142,7 @@ where
span: DUMMY_SP,
body: Some(BlockStmt {
span: DUMMY_SP,
stmts,
stmts: vec![return_stmt],
}),
is_generator: false,
is_async,
@ -183,7 +178,7 @@ where
}],
};
module_items.push(ModuleItem::Stmt(Stmt::Decl(Decl::Var(var_decl))));
module.append(id, ModuleItem::Stmt(Stmt::Decl(Decl::Var(var_decl))));
// print_hygiene(
// "wrap",
@ -195,15 +190,7 @@ where
// },
// );
Ok(Modules::from(
id,
Module {
span: DUMMY_SP,
shebang: None,
body: module_items,
},
self.injected_ctxt,
))
Ok(module)
}
}
@ -229,16 +216,19 @@ struct ExportToReturn {
}
impl ExportToReturn {
fn export_id(&mut self, i: Ident) {
fn export_id(&mut self, mut i: Ident) {
i.span.ctxt = SyntaxContext::empty();
self.return_props
.push(PropOrSpread::Prop(Box::new(Prop::Shorthand(i.clone()))));
.push(PropOrSpread::Prop(Box::new(Prop::Shorthand(i))));
}
fn export_key_value(&mut self, key: Ident, value: Ident) {
fn export_key_value(&mut self, mut key: Ident, value: Ident) {
key.span.ctxt = SyntaxContext::empty();
self.return_props
.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
key: PropName::Ident(key.clone()),
value: Box::new(Expr::Ident(value.clone())),
key: PropName::Ident(key),
value: Box::new(Expr::Ident(value)),
}))));
}
}
@ -346,23 +336,4 @@ impl Fold for ExportToReturn {
ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP }))
}
}
fn fold_module_items(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
let mut new = items.fold_children_with(self);
new.retain(|s| match s {
ModuleItem::Stmt(Stmt::Empty(..)) => false,
_ => true,
});
new.push(ModuleItem::Stmt(Stmt::Return(ReturnStmt {
span: DUMMY_SP,
arg: Some(Box::new(Expr::Object(ObjectLit {
span: DUMMY_SP,
props: take(&mut self.return_props),
}))),
})));
new
}
}

View File

@ -117,12 +117,9 @@ where
});
} else {
dep = dep.fold_with(&mut DepUnexporter {});
// print_hygiene(&format!("dep: unexport"), &self.cm,
// &dep.clone().into());
}
// TODO: Add varaible based on specifers
// print_hygiene(&format!("done: reexport"), &self.cm, &dep.clone().into());
Ok(dep)
})

View File

@ -143,7 +143,11 @@ where
}
};
// print_hygiene("wrapped: before deps", &self.cm, &module);
// print_hygiene(
// &format!("wrapped: before deps: {:?}", dep_id),
// &self.cm,
// &module.clone().into(),
// );
if let Some(plan) = ctx.plan.circular.get(&dep_id) {
module = self
@ -155,6 +159,12 @@ where
.merge_deps(ctx, false, module, plan, &dep_info, false)
.context("failed to merge dependencies")?;
// print_hygiene(
// &format!("wrapped: after deps: {:?}", dep_id),
// &self.cm,
// &module.clone().into(),
// );
// This code is currently not required because wrapped es modules store their
// content on the top scope.
//
@ -183,6 +193,12 @@ where
} else {
let mut module = self.merge_modules(ctx, dep_id, false, true)?;
// print_hygiene(
// &format!("not-wrapped: after deps: {:?}", dep_id),
// &self.cm,
// &module.clone().into(),
// );
// print_hygiene(
// &format!(
// "import: Before handle_import_deps {:?}:{:?}",
@ -409,6 +425,8 @@ where
source.unwrap().clone(),
);
// print_hygiene("merged as reexport", &self.cm, &module.clone().into());
log::debug!(
"Merged {} into {} as a reexport",
dep_info.fm.name,
@ -1074,7 +1092,6 @@ where
new.push(ModuleItem::Stmt(Stmt::Decl(Decl::Var(v))));
log::trace!("Exporting `default` with `export decl``");
let export =
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport {
span: export.span.with_ctxt(injected_ctxt),
@ -1086,6 +1103,12 @@ where
id.span.with_ctxt(info.export_ctxt()),
);
log::trace!(
"Exporting `{}{:?}` with `export decl`",
id.sym,
id.span.ctxt
);
new.push(
id.clone()
.assign_to(exported.clone())

View File

@ -1033,3 +1033,63 @@ fn deno_8302_3() {
Ok(())
});
}
#[test]
fn deno_9307_1() {
suite()
.file(
"main.js",
"
export * as G from './a';
",
)
.file("a.js", "")
.run(|t| {
let module = t
.bundler
.load_transformed(&FileName::Real("main.js".into()))?
.unwrap();
let mut entries = AHashMap::default();
entries.insert("main.js".to_string(), module.clone());
let p = t.bundler.calculate_plan(entries)?;
dbg!(&p);
assert_normal(t, &p.0, "main", &["a"]);
assert_normal(t, &p.0, "a", &[]);
Ok(())
});
}
#[test]
fn deno_9307_2() {
suite()
.file(
"main.js",
"
export * from './a';
",
)
.file("a.js", "")
.run(|t| {
let module = t
.bundler
.load_transformed(&FileName::Real("main.js".into()))?
.unwrap();
let mut entries = AHashMap::default();
entries.insert("main.js".to_string(), module.clone());
let p = t.bundler.calculate_plan(entries)?;
dbg!(&p);
assert_normal(t, &p.0, "main", &["a"]);
assert_normal(t, &p.0, "a", &[]);
Ok(())
});
}

View File

@ -27,6 +27,10 @@ pub(crate) fn inline(injected_ctxt: SyntaxContext, module: &mut Modules) {
module.visit_with(&mut v);
module.visit_mut_with(&mut v);
module.retain_mut(|_, s| match s {
ModuleItem::Stmt(Stmt::Empty(..)) => false,
_ => true,
});
}
#[derive(Debug)]

View File

@ -0,0 +1,68 @@
// Loaded from https://deno.land/std/fs/ensure_file.ts
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
import * as path from "../path/mod.ts";
import { ensureDir, ensureDirSync } from "./ensure_dir.ts";
import { getFileInfoType } from "./_util.ts";
/**
* Ensures that the file exists.
* If the file that is requested to be created is in directories that do not
* exist.
* these directories are created. If the file already exists,
* it is NOTMODIFIED.
* Requires the `--allow-read` and `--allow-write` flag.
*/
export async function ensureFile(filePath: string): Promise<void> {
try {
// if file exists
const stat = await Deno.lstat(filePath);
if (!stat.isFile) {
throw new Error(
`Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'`,
);
}
} catch (err) {
// if file not exists
if (err instanceof Deno.errors.NotFound) {
// ensure dir exists
await ensureDir(path.dirname(filePath));
// create file
await Deno.writeFile(filePath, new Uint8Array());
return;
}
throw err;
}
}
/**
* Ensures that the file exists.
* If the file that is requested to be created is in directories that do not
* exist,
* these directories are created. If the file already exists,
* it is NOT MODIFIED.
* Requires the `--allow-read` and `--allow-write` flag.
*/
export function ensureFileSync(filePath: string): void {
try {
// if file exists
const stat = Deno.lstatSync(filePath);
if (!stat.isFile) {
throw new Error(
`Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'`,
);
}
} catch (err) {
// if file not exists
if (err instanceof Deno.errors.NotFound) {
// ensure dir exists
ensureDirSync(path.dirname(filePath));
// create file
Deno.writeFileSync(filePath, new Uint8Array());
return;
}
throw err;
}
}

View File

@ -0,0 +1,61 @@
// Loaded from https://deno.land/x/god_crypto@v0.2.0/src/rsa.ts
import { power_mod } from "./math.ts";
import { eme_oaep_encode, eme_oaep_decode } from "./eme_oaep.ts";
import { os2ip, i2osp } from "./primitives.ts";
import { concat, random_bytes } from "./helper.ts";
/**
* @param n public key modulus
* @param e public key exponent
* @param m message representative
*/
export function rsaep(n: bigint, e: bigint, m: bigint): bigint {
return power_mod(m, e, n);
}
/**
* @param n private key modulus
* @param d private key exponent
* @param c ciphertext representative
*/
export function rsadp(n: bigint, d: bigint, c: bigint): bigint {
return power_mod(c, d, n);
}
export function rsa_oaep_encrypt(bytes: number, n: bigint, e: bigint, m: Uint8Array, algorithm: "sha1" | "sha256") {
const em = eme_oaep_encode(new Uint8Array(0), m, bytes, algorithm);
const msg = os2ip(em);
const c = rsaep(n, e, msg);
return i2osp(c, bytes);
}
export function rsa_oaep_decrypt(bytes: number, n: bigint, d: bigint, c: Uint8Array, algorithm: "sha1" | "sha256") {
const em = rsadp(n, d, os2ip(c));
const m = eme_oaep_decode(new Uint8Array(0), i2osp(em, bytes), bytes, algorithm);
return m;
}
export function rsa_pkcs1_encrypt(bytes: number, n: bigint, e: bigint, m: Uint8Array) {
const p = concat([0x00, 0x02], random_bytes(bytes - m.length - 3), [0x00], m);
const msg = os2ip(p);
const c = rsaep(n, e, msg);
return i2osp(c, bytes);
}
export function rsa_pkcs1_decrypt(bytes: number, n: bigint, d: bigint, c: Uint8Array) {
const em = i2osp(rsadp(n, d, os2ip(c)), bytes);
if (em[0] !== 0) throw "Decryption error";
if (em[1] !== 0x02) throw "Decryption error";
let psCursor = 2;
for(; psCursor < em.length; psCursor++) {
if (em[psCursor] === 0x00) break;
}
if (psCursor < 10) throw "Decryption error";
return em.slice(psCursor + 1);
}

View File

@ -0,0 +1,34 @@
// Loaded from https://deno.land/x/deno_image@v0.0.3/lib/decoders/fast-png/common.ts
export const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10];
const crcTable: number[] = [];
for (let n = 0; n < 256; n++) {
let c = n;
for (let k = 0; k < 8; k++) {
if (c & 1) {
c = 0xedb88320 ^ (c >>> 1);
} else {
c = c >>> 1;
}
}
crcTable[n] = c;
}
const initialCrc = 0xffffffff;
function updateCrc(
currentCrc: number,
data: Uint8Array,
length: number,
): number {
let c = currentCrc;
for (let n = 0; n < length; n++) {
c = crcTable[(c ^ data[n]) & 0xff] ^ (c >>> 8);
}
return c;
}
export function crc(data: Uint8Array, length: number): number {
return (updateCrc(initialCrc, data, length) ^ initialCrc) >>> 0;
}

View File

@ -0,0 +1,114 @@
// Loaded from https://deno.land/std/encoding/hex.ts
// Ported from Go
// https://github.com/golang/go/blob/go1.12.5/src/encoding/hex/hex.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
const hexTable = new TextEncoder().encode("0123456789abcdef");
/**
* ErrInvalidByte takes an invalid byte and returns an Error.
* @param byte
*/
export function errInvalidByte(byte: number): Error {
return new Error(
"encoding/hex: invalid byte: " +
new TextDecoder().decode(new Uint8Array([byte])),
);
}
/** ErrLength returns an error about odd string length. */
export function errLength(): Error {
return new Error("encoding/hex: odd length hex string");
}
// fromHexChar converts a hex character into its value.
function fromHexChar(byte: number): number {
// '0' <= byte && byte <= '9'
if (48 <= byte && byte <= 57) return byte - 48;
// 'a' <= byte && byte <= 'f'
if (97 <= byte && byte <= 102) return byte - 97 + 10;
// 'A' <= byte && byte <= 'F'
if (65 <= byte && byte <= 70) return byte - 65 + 10;
throw errInvalidByte(byte);
}
/**
* EncodedLen returns the length of an encoding of n source bytes. Specifically,
* it returns n * 2.
* @param n
*/
export function encodedLen(n: number): number {
return n * 2;
}
/**
* Encode encodes `src` into `encodedLen(src.length)` bytes.
* @param src
*/
export function encode(src: Uint8Array): Uint8Array {
const dst = new Uint8Array(encodedLen(src.length));
for (let i = 0; i < dst.length; i++) {
const v = src[i];
dst[i * 2] = hexTable[v >> 4];
dst[i * 2 + 1] = hexTable[v & 0x0f];
}
return dst;
}
/**
* EncodeToString returns the hexadecimal encoding of `src`.
* @param src
*/
export function encodeToString(src: Uint8Array): string {
return new TextDecoder().decode(encode(src));
}
/**
* Decode decodes `src` into `decodedLen(src.length)` bytes
* If the input is malformed an error will be thrown
* the error.
* @param src
*/
export function decode(src: Uint8Array): Uint8Array {
const dst = new Uint8Array(decodedLen(src.length));
for (let i = 0; i < dst.length; i++) {
const a = fromHexChar(src[i * 2]);
const b = fromHexChar(src[i * 2 + 1]);
dst[i] = (a << 4) | b;
}
if (src.length % 2 == 1) {
// Check for invalid char before reporting bad length,
// since the invalid char (if present) is an earlier problem.
fromHexChar(src[dst.length * 2]);
throw errLength();
}
return dst;
}
/**
* DecodedLen returns the length of decoding `x` source bytes.
* Specifically, it returns `x / 2`.
* @param x
*/
export function decodedLen(x: number): number {
return x >>> 1;
}
/**
* DecodeString returns the bytes represented by the hexadecimal string `s`.
* DecodeString expects that src contains only hexadecimal characters and that
* src has even length.
* If the input is malformed, DecodeString will throw an error.
* @param s the `string` to decode to `Uint8Array`
*/
export function decodeString(s: string): Uint8Array {
return decode(new TextEncoder().encode(s));
}

View File

@ -0,0 +1,9 @@
// Loaded from https://deno.land/std@0.85.0/io/mod.ts
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
export * from "./bufio.ts";
export * from "./ioutil.ts";
export * from "./readers.ts";
export * from "./writers.ts";
export * from "./streams.ts";

View File

@ -0,0 +1,16 @@
// Loaded from https://deno.land/x/segno@v1.1.0/lib/validations/isBtcAddress.ts
// @ts-ignore allowing typedoc to build
import { assertString } from '../helpers/assertString.ts';
// supports Bech32 addresses
/**
* @ignore
*/
const btc = /^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$/;
export const isBtcAddress = (str: string) => {
assertString(str);
return btc.test(str);
};

View File

@ -0,0 +1,21 @@
// Loaded from https://deno.land/std@0.79.0/_util/os.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
export const osType = (() => {
if (globalThis.Deno != null) {
return Deno.build.os;
}
// deno-lint-ignore no-explicit-any
const navigator = (globalThis as any).navigator;
if (navigator?.appVersion?.includes?.("Win") ?? false) {
return "windows";
}
return "linux";
})();
export const isWindows = osType === "windows";

View File

@ -0,0 +1,36 @@
// Loaded from https://deno.land/x/graphql_deno@v15.0.0/lib/validation/rules/UniqueArgumentNamesRule.js
import { GraphQLError } from '../../error/GraphQLError.js';
/**
* Unique argument names
*
* A GraphQL field or directive is only valid if all supplied arguments are
* uniquely named.
*/
export function UniqueArgumentNamesRule(context) {
let knownArgNames = Object.create(null);
return {
Field() {
knownArgNames = Object.create(null);
},
Directive() {
knownArgNames = Object.create(null);
},
Argument(node) {
const argName = node.name.value;
if (knownArgNames[argName]) {
context.reportError(new GraphQLError(`There can be only one argument named "${argName}".`, [knownArgNames[argName], node.name]));
} else {
knownArgNames[argName] = node.name;
}
return false;
}
};
}

View File

@ -0,0 +1,34 @@
// Loaded from https://deno.land/std@0.74.0/fs/exists.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
/**
* Test whether or not the given path exists by checking with the file system
*/
export async function exists(filePath: string): Promise<boolean> {
try {
await Deno.lstat(filePath);
return true;
} catch (err) {
if (err instanceof Deno.errors.NotFound) {
return false;
}
throw err;
}
}
/**
* Test whether or not the given path exists by checking with the file system
*/
export function existsSync(filePath: string): boolean {
try {
Deno.lstatSync(filePath);
return true;
} catch (err) {
if (err instanceof Deno.errors.NotFound) {
return false;
}
throw err;
}
}

View File

@ -0,0 +1,4 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/mod.ts
export * from "./source/index.js";

View File

@ -0,0 +1,49 @@
// Loaded from https://deno.land/x/deno_image@v0.0.3/lib/decoders/fast-png/pako/lib/zlib/adler32.js
// Note: adler32 takes 12% for level 0 and 2% for level 6.
// It isn't worth it to make additional optimizations as in original.
// Small size is preferable.
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
export function adler32(adler, buf, len, pos) {
var s1 = (adler & 0xffff) |0,
s2 = ((adler >>> 16) & 0xffff) |0,
n = 0;
while (len !== 0) {
// Set limit ~ twice less than 5552, to keep
// s2 in 31-bits, because we force signed ints.
// in other case %= will fail.
n = len > 2000 ? 2000 : len;
len -= n;
do {
s1 = (s1 + buf[pos++]) |0;
s2 = (s2 + s1) |0;
} while (--n);
s1 %= 65521;
s2 %= 65521;
}
return (s1 | (s2 << 16)) |0;
}

View File

@ -0,0 +1,6 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/internal/_isRegExp.js
export default function _isRegExp(x) {
return Object.prototype.toString.call(x) === '[object RegExp]';
}

View File

@ -0,0 +1,110 @@
// Loaded from https://deno.land/x/djwt@v1.9/_signature.ts
import type { Algorithm } from "./_algorithm.ts";
import {
base64url,
convertHexToUint8Array,
HmacSha256,
HmacSha512,
RSA,
} from "./_depts.ts";
function assertNever(alg: never, message: string): never {
throw new RangeError(message);
}
export function convertHexToBase64url(input: string): string {
return base64url.encode(convertHexToUint8Array(input));
}
/**
* Do a constant time string comparison. Always compare the complete strings
* against each other to get a constant time. This method does not short-cut
* if the two string's length differs.
* CREDIT: https://github.com/Bruce17/safe-compare
*/
function safeCompare(a: string, b: string) {
const strA = String(a);
const lenA = strA.length;
let strB = String(b);
let result = 0;
if (lenA !== strB.length) {
strB = strA;
result = 1;
}
for (var i = 0; i < lenA; i++) {
result |= (strA.charCodeAt(i) ^ strB.charCodeAt(i));
}
return result === 0;
}
async function encrypt(
algorithm: Algorithm,
key: string,
message: string,
): Promise<string> {
switch (algorithm) {
case "none":
return "";
case "HS256":
return new HmacSha256(key).update(message).toString();
case "HS512":
return new HmacSha512(key).update(message).toString();
case "RS256":
return (
await new RSA(RSA.parseKey(key)).sign(message, { hash: "sha256" })
).hex();
default:
assertNever(
algorithm,
"no matching crypto algorithm in the header: " + algorithm,
);
}
}
export async function create(
algorithm: Algorithm,
key: string,
input: string,
): Promise<string> {
return convertHexToBase64url(await encrypt(algorithm, key, input));
}
export async function verify({
signature,
key,
algorithm,
signingInput,
}: {
signature: string;
key: string;
algorithm: Algorithm;
signingInput: string;
}): Promise<boolean> {
switch (algorithm) {
case "none":
case "HS256":
case "HS512": {
return safeCompare(
signature,
(await encrypt(algorithm, key, signingInput)),
);
}
case "RS256": {
return await new RSA(RSA.parseKey(key)).verify(
convertHexToUint8Array(signature),
signingInput,
{ hash: "sha256" },
);
}
default:
assertNever(
algorithm,
"no matching crypto algorithm in the header: " + algorithm,
);
}
}

View File

@ -0,0 +1,4 @@
// Loaded from https://deno.land/x/graphql_deno@v15.0.0/lib/subscription/index.js
export { subscribe, createSourceEventStream } from './subscribe.js';

View File

@ -0,0 +1,8 @@
// Loaded from https://deno.land/x/case/paramCase.ts
import normalCase from "./normalCase.ts";
export default function paramCase(value: string, locale?: string): string {
return normalCase(value, locale, "-");
}

View File

@ -0,0 +1,82 @@
// Loaded from https://deno.land/std@0.78.0/encoding/_yaml/mark.ts
// Ported from js-yaml v3.13.1:
// https://github.com/nodeca/js-yaml/commit/665aadda42349dcae869f12040d9b10ef18d12da
// Copyright 2011-2015 by Vitaly Puzrin. All rights reserved. MIT license.
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { repeat } from "./utils.ts";
export class Mark {
constructor(
public name: string,
public buffer: string,
public position: number,
public line: number,
public column: number,
) {}
public getSnippet(indent = 4, maxLength = 75): string | null {
if (!this.buffer) return null;
let head = "";
let start = this.position;
while (
start > 0 &&
"\x00\r\n\x85\u2028\u2029".indexOf(this.buffer.charAt(start - 1)) === -1
) {
start -= 1;
if (this.position - start > maxLength / 2 - 1) {
head = " ... ";
start += 5;
break;
}
}
let tail = "";
let end = this.position;
while (
end < this.buffer.length &&
"\x00\r\n\x85\u2028\u2029".indexOf(this.buffer.charAt(end)) === -1
) {
end += 1;
if (end - this.position > maxLength / 2 - 1) {
tail = " ... ";
end -= 5;
break;
}
}
const snippet = this.buffer.slice(start, end);
return `${repeat(" ", indent)}${head}${snippet}${tail}\n${
repeat(
" ",
indent + this.position - start + head.length,
)
}^`;
}
public toString(compact?: boolean): string {
let snippet,
where = "";
if (this.name) {
where += `in "${this.name}" `;
}
where += `at line ${this.line + 1}, column ${this.column + 1}`;
if (!compact) {
snippet = this.getSnippet();
if (snippet) {
where += `:\n${snippet}`;
}
}
return where;
}
}

View File

@ -0,0 +1,390 @@
// Loaded from https://deno.land/std@0.80.0/path/glob.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
import { osType } from "../_util/os.ts";
import { join, normalize } from "./mod.ts";
import { SEP, SEP_PATTERN } from "./separator.ts";
export interface GlobOptions {
/** Extended glob syntax.
* See https://www.linuxjournal.com/content/bash-extended-globbing. Defaults
* to true. */
extended?: boolean;
/** Globstar syntax.
* See https://www.linuxjournal.com/content/globstar-new-bash-globbing-option.
* If false, `**` is treated like `*`. Defaults to true. */
globstar?: boolean;
/** Operating system. Defaults to the native OS. */
os?: typeof Deno.build.os;
}
export type GlobToRegExpOptions = GlobOptions;
// deno-fmt-ignore
const regExpEscapeChars = ["!", "$", "(", ")", "*", "+", ".", "=", "?", "[", "\\", "^", "{", "|"];
const rangeEscapeChars = ["-", "\\", "]"];
/** Convert a glob string to a regular expression.
*
* Tries to match bash glob expansion as closely as possible.
*
* Basic glob syntax:
* - `*` - Matches everything without leaving the path segment.
* - `{foo,bar}` - Matches `foo` or `bar`.
* - `[abcd]` - Matches `a`, `b`, `c` or `d`.
* - `[a-d]` - Matches `a`, `b`, `c` or `d`.
* - `[!abcd]` - Matches any single character besides `a`, `b`, `c` or `d`.
* - `[[:<class>:]]` - Matches any character belonging to `<class>`.
* - `[[:alnum:]]` - Matches any digit or letter.
* - `[[:digit:]abc]` - Matches any digit, `a`, `b` or `c`.
* - See https://facelessuser.github.io/wcmatch/glob/#posix-character-classes
* for a complete list of supported character classes.
* - `\` - Escapes the next character for an `os` other than `"windows"`.
* - \` - Escapes the next character for `os` set to `"windows"`.
* - `/` - Path separator.
* - `\` - Additional path separator only for `os` set to `"windows"`.
*
* Extended syntax:
* - Requires `{ extended: true }`.
* - `?(foo|bar)` - Matches 0 or 1 instance of `{foo,bar}`.
* - `@(foo|bar)` - Matches 1 instance of `{foo,bar}`. They behave the same.
* - `*(foo|bar)` - Matches _n_ instances of `{foo,bar}`.
* - `+(foo|bar)` - Matches _n > 0_ instances of `{foo,bar}`.
* - `!(foo|bar)` - Matches anything other than `{foo,bar}`.
* - See https://www.linuxjournal.com/content/bash-extended-globbing.
*
* Globstar syntax:
* - Requires `{ globstar: true }`.
* - `**` - Matches any number of any path segments.
* - Must comprise its entire path segment in the provided glob.
* - See https://www.linuxjournal.com/content/globstar-new-bash-globbing-option.
*
* Note the following properties:
* - The generated `RegExp` is anchored at both start and end.
* - Repeating and trailing separators are tolerated. Trailing separators in the
* provided glob have no meaning and are discarded.
* - Absolute globs will only match absolute paths, etc.
* - Empty globs will match nothing.
* - Any special glob syntax must be contained to one path segment. For example,
* `?(foo|bar/baz)` is invalid. The separator will take precendence and the
* first segment ends with an unclosed group.
* - If a path segment ends with unclosed groups or a dangling escape prefix, a
* parse error has occured. Every character for that segment is taken
* literally in this event.
*
* Limitations:
* - A negative group like `!(foo|bar)` will wrongly be converted to a negative
* look-ahead followed by a wildcard. This means that `!(foo).js` will wrongly
* fail to match `foobar.js`, even though `foobar` is not `foo`. Effectively,
* `!(foo|bar)` is treated like `!(@(foo|bar)*)`. This will work correctly if
* the group occurs not nested at the end of the segment. */
export function globToRegExp(
glob: string,
{ extended = true, globstar: globstarOption = true, os = osType }:
GlobToRegExpOptions = {},
): RegExp {
if (glob == "") {
return /(?!)/;
}
const sep = os == "windows" ? "(?:\\\\|/)+" : "/+";
const sepMaybe = os == "windows" ? "(?:\\\\|/)*" : "/*";
const seps = os == "windows" ? ["\\", "/"] : ["/"];
const globstar = os == "windows"
? "(?:[^\\\\/]*(?:\\\\|/|$)+)*"
: "(?:[^/]*(?:/|$)+)*";
const wildcard = os == "windows" ? "[^\\\\/]*" : "[^/]*";
const escapePrefix = os == "windows" ? "`" : "\\";
// Remove trailing separators.
let newLength = glob.length;
for (; newLength > 1 && seps.includes(glob[newLength - 1]); newLength--);
glob = glob.slice(0, newLength);
let regExpString = "";
// Terminates correctly. Trust that `j` is incremented every iteration.
for (let j = 0; j < glob.length;) {
let segment = "";
const groupStack = [];
let inRange = false;
let inEscape = false;
let endsWithSep = false;
let i = j;
// Terminates with `i` at the non-inclusive end of the current segment.
for (; i < glob.length && !seps.includes(glob[i]); i++) {
if (inEscape) {
inEscape = false;
const escapeChars = inRange ? rangeEscapeChars : regExpEscapeChars;
segment += escapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i];
continue;
}
if (glob[i] == escapePrefix) {
inEscape = true;
continue;
}
if (glob[i] == "[") {
if (!inRange) {
inRange = true;
segment += "[";
if (glob[i + 1] == "!") {
i++;
segment += "^";
} else if (glob[i + 1] == "^") {
i++;
segment += "\\^";
}
continue;
} else if (glob[i + 1] == ":") {
let k = i + 1;
let value = "";
while (glob[k + 1] != null && glob[k + 1] != ":") {
value += glob[k + 1];
k++;
}
if (glob[k + 1] == ":" && glob[k + 2] == "]") {
i = k + 2;
if (value == "alnum") segment += "\\dA-Za-z";
else if (value == "alpha") segment += "A-Za-z";
else if (value == "ascii") segment += "\x00-\x7F";
else if (value == "blank") segment += "\t ";
else if (value == "cntrl") segment += "\x00-\x1F\x7F";
else if (value == "digit") segment += "\\d";
else if (value == "graph") segment += "\x21-\x7E";
else if (value == "lower") segment += "a-z";
else if (value == "print") segment += "\x20-\x7E";
else if (value == "punct") {
segment += "!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_{|}~";
} else if (value == "space") segment += "\\s\v";
else if (value == "upper") segment += "A-Z";
else if (value == "word") segment += "\\w";
else if (value == "xdigit") segment += "\\dA-Fa-f";
continue;
}
}
}
if (glob[i] == "]" && inRange) {
inRange = false;
segment += "]";
continue;
}
if (inRange) {
if (glob[i] == "\\") {
segment += `\\\\`;
} else {
segment += glob[i];
}
continue;
}
if (
glob[i] == ")" && groupStack.length > 0 &&
groupStack[groupStack.length - 1] != "BRACE"
) {
segment += ")";
const type = groupStack.pop()!;
if (type == "!") {
segment += wildcard;
} else if (type != "@") {
segment += type;
}
continue;
}
if (
glob[i] == "|" && groupStack.length > 0 &&
groupStack[groupStack.length - 1] != "BRACE"
) {
segment += "|";
continue;
}
if (glob[i] == "+" && extended && glob[i + 1] == "(") {
i++;
groupStack.push("+");
segment += "(?:";
continue;
}
if (glob[i] == "@" && extended && glob[i + 1] == "(") {
i++;
groupStack.push("@");
segment += "(?:";
continue;
}
if (glob[i] == "?") {
if (extended && glob[i + 1] == "(") {
i++;
groupStack.push("?");
segment += "(?:";
} else {
segment += ".";
}
continue;
}
if (glob[i] == "!" && extended && glob[i + 1] == "(") {
i++;
groupStack.push("!");
segment += "(?!";
continue;
}
if (glob[i] == "{") {
groupStack.push("BRACE");
segment += "(?:";
continue;
}
if (glob[i] == "}" && groupStack[groupStack.length - 1] == "BRACE") {
groupStack.pop();
segment += ")";
continue;
}
if (glob[i] == "," && groupStack[groupStack.length - 1] == "BRACE") {
segment += "|";
continue;
}
if (glob[i] == "*") {
if (extended && glob[i + 1] == "(") {
i++;
groupStack.push("*");
segment += "(?:";
} else {
const prevChar = glob[i - 1];
let numStars = 1;
while (glob[i + 1] == "*") {
i++;
numStars++;
}
const nextChar = glob[i + 1];
if (
globstarOption && numStars == 2 &&
[...seps, undefined].includes(prevChar) &&
[...seps, undefined].includes(nextChar)
) {
segment += globstar;
endsWithSep = true;
} else {
segment += wildcard;
}
}
continue;
}
segment += regExpEscapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i];
}
// Check for unclosed groups or a dangling backslash.
if (groupStack.length > 0 || inRange || inEscape) {
// Parse failure. Take all characters from this segment literally.
segment = "";
for (const c of glob.slice(j, i)) {
segment += regExpEscapeChars.includes(c) ? `\\${c}` : c;
endsWithSep = false;
}
}
regExpString += segment;
if (!endsWithSep) {
regExpString += i < glob.length ? sep : sepMaybe;
endsWithSep = true;
}
// Terminates with `i` at the start of the next segment.
while (seps.includes(glob[i])) i++;
// Check that the next value of `j` is indeed higher than the current value.
if (!(i > j)) {
throw new Error("Assertion failure: i > j (potential infinite loop)");
}
j = i;
}
regExpString = `^${regExpString}$`;
return new RegExp(regExpString);
}
/** Test whether the given string is a glob */
export function isGlob(str: string): boolean {
const chars: Record<string, string> = { "{": "}", "(": ")", "[": "]" };
const regex =
/\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/;
if (str === "") {
return false;
}
let match: RegExpExecArray | null;
while ((match = regex.exec(str))) {
if (match[2]) return true;
let idx = match.index + match[0].length;
// if an open bracket/brace/paren is escaped,
// set the index to the next closing character
const open = match[1];
const close = open ? chars[open] : null;
if (open && close) {
const n = str.indexOf(close, idx);
if (n !== -1) {
idx = n + 1;
}
}
str = str.slice(idx);
}
return false;
}
/** Like normalize(), but doesn't collapse "**\/.." when `globstar` is true. */
export function normalizeGlob(
glob: string,
{ globstar = false }: GlobOptions = {},
): string {
if (glob.match(/\0/g)) {
throw new Error(`Glob contains invalid characters: "${glob}"`);
}
if (!globstar) {
return normalize(glob);
}
const s = SEP_PATTERN.source;
const badParentPattern = new RegExp(
`(?<=(${s}|^)\\*\\*${s})\\.\\.(?=${s}|$)`,
"g",
);
return normalize(glob.replace(badParentPattern, "\0")).replace(/\0/g, "..");
}
/** Like join(), but doesn't collapse "**\/.." when `globstar` is true. */
export function joinGlobs(
globs: string[],
{ extended = false, globstar = false }: GlobOptions = {},
): string {
if (!globstar || globs.length == 0) {
return join(...globs);
}
if (globs.length === 0) return ".";
let joined: string | undefined;
for (const glob of globs) {
const path = glob;
if (path.length > 0) {
if (!joined) joined = path;
else joined += `${SEP}${path}`;
}
}
if (!joined) return ".";
return normalizeGlob(joined, { extended, globstar });
}

View File

@ -0,0 +1,36 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/equals.js
import _curry2 from './internal/_curry2.js';
import _equals from './internal/_equals.js';
/**
* Returns `true` if its arguments are equivalent, `false` otherwise. Handles
* cyclical data structures.
*
* Dispatches symmetrically to the `equals` methods of both arguments, if
* present.
*
* @func
* @memberOf R
* @since v0.15.0
* @category Relation
* @sig a -> b -> Boolean
* @param {*} a
* @param {*} b
* @return {Boolean}
* @example
*
* R.equals(1, 1); //=> true
* R.equals(1, '1'); //=> false
* R.equals([1, 2, 3], [1, 2, 3]); //=> true
*
* const a = {}; a.v = a;
* const b = {}; b.v = b;
* R.equals(a, b); //=> true
*/
var equals = _curry2(function equals(a, b) {
return _equals(a, b, [], []);
});
export default equals;

View File

@ -0,0 +1,21 @@
// Loaded from https://deno.land/x/segno@v1.1.0/lib/validations/isUUID.ts
// @ts-ignore allowing typedoc to build
import { assertString } from '../helpers/assertString.ts';
/**
* @ignore
*/
const uuid = {
3: /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
4: /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
5: /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
};
export const isUUID = (str: string, version: 3 | 4 | 5 | 'all' = 'all') => {
assertString(str);
const pattern = (uuid as any)[version];
return pattern && pattern.test(str);
};

View File

@ -0,0 +1,512 @@
// Loaded from https://deno.land/x/deno_image@v0.0.3/lib/decoders/fast-png/iobuffer/IOBuffer.ts
import { decode, encode } from './utf8.ts';
const defaultByteLength = 1024 * 8;
type InputData = number | ArrayBufferLike | ArrayBufferView | IOBuffer;
interface IOBufferOptions {
/**
* Ignore the first n bytes of the ArrayBuffer.
*/
offset?: number;
}
export class IOBuffer {
/**
* Reference to the internal ArrayBuffer object.
*/
public buffer: ArrayBufferLike;
/**
* Byte length of the internal ArrayBuffer.
*/
public byteLength: number;
/**
* Byte offset of the internal ArrayBuffer.
*/
public byteOffset: number;
/**
* Byte length of the internal ArrayBuffer.
*/
public length: number;
/**
* The current offset of the buffer's pointer.
*/
public offset: number;
private lastWrittenByte: number;
private littleEndian: boolean;
private _data: DataView;
private _mark: number;
private _marks: number[];
/**
* @param data - The data to construct the IOBuffer with.
* If data is a number, it will be the new buffer's length<br>
* If data is `undefined`, the buffer will be initialized with a default length of 8Kb<br>
* If data is an ArrayBuffer, SharedArrayBuffer, an ArrayBufferView (Typed Array) or an IOBuffer instance
* a view will be created over the underlying ArrayBuffer.
* @param options
*/
public constructor(
data: InputData = defaultByteLength,
options: IOBufferOptions = {},
) {
let dataIsGiven = false;
if (typeof data === 'number') {
data = new ArrayBuffer(data);
} else {
dataIsGiven = true;
this.lastWrittenByte = data.byteLength;
}
const offset = options.offset ? options.offset >>> 0 : 0;
const byteLength = data.byteLength - offset;
let dvOffset = offset;
if (ArrayBuffer.isView(data) || data instanceof IOBuffer) {
if (data.byteLength !== data.buffer.byteLength) {
dvOffset = data.byteOffset + offset;
}
data = data.buffer;
}
if (dataIsGiven) {
this.lastWrittenByte = byteLength;
} else {
this.lastWrittenByte = 0;
}
this.buffer = data;
this.length = byteLength;
this.byteLength = byteLength;
this.byteOffset = dvOffset;
this.offset = 0;
this.littleEndian = true;
this._data = new DataView(this.buffer, dvOffset, byteLength);
this._mark = 0;
this._marks = [];
}
/**
* Checks if the memory allocated to the buffer is sufficient to store more
* bytes after the offset.
* @param byteLength - The needed memory in bytes.
* @returns `true` if there is sufficient space and `false` otherwise.
*/
public available(byteLength = 1): boolean {
return this.offset + byteLength <= this.length;
}
/**
* Check if little-endian mode is used for reading and writing multi-byte
* values.
* @returns `true` if little-endian mode is used, `false` otherwise.
*/
public isLittleEndian(): boolean {
return this.littleEndian;
}
/**
* Set little-endian mode for reading and writing multi-byte values.
*/
public setLittleEndian(): this {
this.littleEndian = true;
return this;
}
/**
* Check if big-endian mode is used for reading and writing multi-byte values.
* @returns `true` if big-endian mode is used, `false` otherwise.
*/
public isBigEndian(): boolean {
return !this.littleEndian;
}
/**
* Switches to big-endian mode for reading and writing multi-byte values.
*/
public setBigEndian(): this {
this.littleEndian = false;
return this;
}
/**
* Move the pointer n bytes forward.
* @param n - Number of bytes to skip.
*/
public skip(n = 1): this {
this.offset += n;
return this;
}
/**
* Move the pointer to the given offset.
* @param offset
*/
public seek(offset: number): this {
this.offset = offset;
return this;
}
/**
* Store the current pointer offset.
* @see {@link IOBuffer#reset}
*/
public mark(): this {
this._mark = this.offset;
return this;
}
/**
* Move the pointer back to the last pointer offset set by mark.
* @see {@link IOBuffer#mark}
*/
public reset(): this {
this.offset = this._mark;
return this;
}
/**
* Push the current pointer offset to the mark stack.
* @see {@link IOBuffer#popMark}
*/
public pushMark(): this {
this._marks.push(this.offset);
return this;
}
/**
* Pop the last pointer offset from the mark stack, and set the current
* pointer offset to the popped value.
* @see {@link IOBuffer#pushMark}
*/
public popMark(): this {
const offset = this._marks.pop();
if (offset === undefined) {
throw new Error('Mark stack empty');
}
this.seek(offset);
return this;
}
/**
* Move the pointer offset back to 0.
*/
public rewind(): this {
this.offset = 0;
return this;
}
/**
* Make sure the buffer has sufficient memory to write a given byteLength at
* the current pointer offset.
* If the buffer's memory is insufficient, this method will create a new
* buffer (a copy) with a length that is twice (byteLength + current offset).
* @param byteLength
*/
public ensureAvailable(byteLength = 1): this {
if (!this.available(byteLength)) {
const lengthNeeded = this.offset + byteLength;
const newLength = lengthNeeded * 2;
const newArray = new Uint8Array(newLength);
newArray.set(new Uint8Array(this.buffer));
this.buffer = newArray.buffer;
this.length = this.byteLength = newLength;
this._data = new DataView(this.buffer);
}
return this;
}
/**
* Read a byte and return false if the byte's value is 0, or true otherwise.
* Moves pointer forward by one byte.
*/
public readBoolean(): boolean {
return this.readUint8() !== 0;
}
/**
* Read a signed 8-bit integer and move pointer forward by 1 byte.
*/
public readInt8(): number {
return this._data.getInt8(this.offset++);
}
/**
* Read an unsigned 8-bit integer and move pointer forward by 1 byte.
*/
public readUint8(): number {
return this._data.getUint8(this.offset++);
}
/**
* Alias for {@link IOBuffer#readUint8}.
*/
public readByte(): number {
return this.readUint8();
}
/**
* Read `n` bytes and move pointer forward by `n` bytes.
*/
public readBytes(n = 1): Uint8Array {
const bytes = new Uint8Array(n);
for (let i = 0; i < n; i++) {
bytes[i] = this.readByte();
}
return bytes;
}
/**
* Read a 16-bit signed integer and move pointer forward by 2 bytes.
*/
public readInt16(): number {
const value = this._data.getInt16(this.offset, this.littleEndian);
this.offset += 2;
return value;
}
/**
* Read a 16-bit unsigned integer and move pointer forward by 2 bytes.
*/
public readUint16(): number {
const value = this._data.getUint16(this.offset, this.littleEndian);
this.offset += 2;
return value;
}
/**
* Read a 32-bit signed integer and move pointer forward by 4 bytes.
*/
public readInt32(): number {
const value = this._data.getInt32(this.offset, this.littleEndian);
this.offset += 4;
return value;
}
/**
* Read a 32-bit unsigned integer and move pointer forward by 4 bytes.
*/
public readUint32(): number {
const value = this._data.getUint32(this.offset, this.littleEndian);
this.offset += 4;
return value;
}
/**
* Read a 32-bit floating number and move pointer forward by 4 bytes.
*/
public readFloat32(): number {
const value = this._data.getFloat32(this.offset, this.littleEndian);
this.offset += 4;
return value;
}
/**
* Read a 64-bit floating number and move pointer forward by 8 bytes.
*/
public readFloat64(): number {
const value = this._data.getFloat64(this.offset, this.littleEndian);
this.offset += 8;
return value;
}
/**
* Read a 1-byte ASCII character and move pointer forward by 1 byte.
*/
public readChar(): string {
return String.fromCharCode(this.readInt8());
}
/**
* Read `n` 1-byte ASCII characters and move pointer forward by `n` bytes.
*/
public readChars(n = 1): string {
let result = '';
for (let i = 0; i < n; i++) {
result += this.readChar();
}
return result;
}
/**
* Read the next `n` bytes, return a UTF-8 decoded string and move pointer
* forward by `n` bytes.
*/
public readUtf8(n = 1): string {
return decode(this.readBytes(n));
}
/**
* Write 0xff if the passed value is truthy, 0x00 otherwise and move pointer
* forward by 1 byte.
*/
public writeBoolean(value: unknown): this {
this.writeUint8(value ? 0xff : 0x00);
return this;
}
/**
* Write `value` as an 8-bit signed integer and move pointer forward by 1 byte.
*/
public writeInt8(value: number): this {
this.ensureAvailable(1);
this._data.setInt8(this.offset++, value);
this._updateLastWrittenByte();
return this;
}
/**
* Write `value` as an 8-bit unsigned integer and move pointer forward by 1
* byte.
*/
public writeUint8(value: number): this {
this.ensureAvailable(1);
this._data.setUint8(this.offset++, value);
this._updateLastWrittenByte();
return this;
}
/**
* An alias for {@link IOBuffer#writeUint8}.
*/
public writeByte(value: number): this {
return this.writeUint8(value);
}
/**
* Write all elements of `bytes` as uint8 values and move pointer forward by
* `bytes.length` bytes.
*/
public writeBytes(bytes: ArrayLike<number>): this {
this.ensureAvailable(bytes.length);
for (let i = 0; i < bytes.length; i++) {
this._data.setUint8(this.offset++, bytes[i]);
}
this._updateLastWrittenByte();
return this;
}
/**
* Write `value` as a 16-bit signed integer and move pointer forward by 2
* bytes.
*/
public writeInt16(value: number): this {
this.ensureAvailable(2);
this._data.setInt16(this.offset, value, this.littleEndian);
this.offset += 2;
this._updateLastWrittenByte();
return this;
}
/**
* Write `value` as a 16-bit unsigned integer and move pointer forward by 2
* bytes.
*/
public writeUint16(value: number): this {
this.ensureAvailable(2);
this._data.setUint16(this.offset, value, this.littleEndian);
this.offset += 2;
this._updateLastWrittenByte();
return this;
}
/**
* Write `value` as a 32-bit signed integer and move pointer forward by 4
* bytes.
*/
public writeInt32(value: number): this {
this.ensureAvailable(4);
this._data.setInt32(this.offset, value, this.littleEndian);
this.offset += 4;
this._updateLastWrittenByte();
return this;
}
/**
* Write `value` as a 32-bit unsigned integer and move pointer forward by 4
* bytes.
*/
public writeUint32(value: number): this {
this.ensureAvailable(4);
this._data.setUint32(this.offset, value, this.littleEndian);
this.offset += 4;
this._updateLastWrittenByte();
return this;
}
/**
* Write `value` as a 32-bit floating number and move pointer forward by 4
* bytes.
*/
public writeFloat32(value: number): this {
this.ensureAvailable(4);
this._data.setFloat32(this.offset, value, this.littleEndian);
this.offset += 4;
this._updateLastWrittenByte();
return this;
}
/**
* Write `value` as a 64-bit floating number and move pointer forward by 8
* bytes.
*/
public writeFloat64(value: number): this {
this.ensureAvailable(8);
this._data.setFloat64(this.offset, value, this.littleEndian);
this.offset += 8;
this._updateLastWrittenByte();
return this;
}
/**
* Write the charCode of `str`'s first character as an 8-bit unsigned integer
* and move pointer forward by 1 byte.
*/
public writeChar(str: string): this {
return this.writeUint8(str.charCodeAt(0));
}
/**
* Write the charCodes of all `str`'s characters as 8-bit unsigned integers
* and move pointer forward by `str.length` bytes.
*/
public writeChars(str: string): this {
for (let i = 0; i < str.length; i++) {
this.writeUint8(str.charCodeAt(i));
}
return this;
}
/**
* UTF-8 encode and write `str` to the current pointer offset and move pointer
* forward according to the encoded length.
*/
public writeUtf8(str: string): this {
return this.writeBytes(encode(str));
}
/**
* Export a Uint8Array view of the internal buffer.
* The view starts at the byte offset and its length
* is calculated to stop at the last written byte or the original length.
*/
public toArray(): Uint8Array {
return new Uint8Array(this.buffer, this.byteOffset, this.lastWrittenByte);
}
/**
* Update the last written byte offset
* @private
*/
private _updateLastWrittenByte(): void {
if (this.offset > this.lastWrittenByte) {
this.lastWrittenByte = this.offset;
}
}
}

View File

@ -0,0 +1,128 @@
// Loaded from https://deno.land/x/mysql/src/packets/parsers/result.ts
import type { BufferReader } from "../../buffer.ts";
import {
MYSQL_TYPE_DATE,
MYSQL_TYPE_DATETIME,
MYSQL_TYPE_DATETIME2,
MYSQL_TYPE_DECIMAL,
MYSQL_TYPE_DOUBLE,
MYSQL_TYPE_FLOAT,
MYSQL_TYPE_INT24,
MYSQL_TYPE_LONG,
MYSQL_TYPE_LONGLONG,
MYSQL_TYPE_NEWDATE,
MYSQL_TYPE_NEWDECIMAL,
MYSQL_TYPE_SHORT,
MYSQL_TYPE_STRING,
MYSQL_TYPE_TIME,
MYSQL_TYPE_TIME2,
MYSQL_TYPE_TIMESTAMP,
MYSQL_TYPE_TIMESTAMP2,
MYSQL_TYPE_TINY,
MYSQL_TYPE_VAR_STRING,
MYSQL_TYPE_VARCHAR,
} from "../../constant/mysql_types.ts";
/** @ignore */
export interface FieldInfo {
catalog: string;
schema: string;
table: string;
originTable: string;
name: string;
originName: string;
encoding: number;
fieldLen: number;
fieldType: number;
fieldFlag: number;
decimals: number;
defaultVal: string;
}
/** @ignore */
export function parseField(reader: BufferReader): FieldInfo {
const catalog = reader.readLenCodeString()!;
const schema = reader.readLenCodeString()!;
const table = reader.readLenCodeString()!;
const originTable = reader.readLenCodeString()!;
const name = reader.readLenCodeString()!;
const originName = reader.readLenCodeString()!;
reader.skip(1);
const encoding = reader.readUint16()!;
const fieldLen = reader.readUint32()!;
const fieldType = reader.readUint8()!;
const fieldFlag = reader.readUint16()!;
const decimals = reader.readUint8()!;
reader.skip(1);
const defaultVal = reader.readLenCodeString()!;
return {
catalog,
schema,
table,
originName,
fieldFlag,
originTable,
fieldLen,
name,
fieldType,
encoding,
decimals,
defaultVal,
};
}
/** @ignore */
export function parseRow(reader: BufferReader, fields: FieldInfo[]): any {
const row: any = {};
for (const field of fields) {
const name = field.name;
const val = reader.readLenCodeString();
row[name] = val === null ? null : convertType(field, val);
}
return row;
}
/** @ignore */
function convertType(field: FieldInfo, val: string): any {
const { fieldType, fieldLen } = field;
switch (fieldType) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DATETIME2:
return parseFloat(val);
case MYSQL_TYPE_NEWDECIMAL:
return val; // #42 MySQL's decimal type cannot be accurately represented by the Number.
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_INT24:
return parseInt(val);
case MYSQL_TYPE_LONGLONG:
if (
Number(val) < Number.MIN_SAFE_INTEGER ||
Number(val) > Number.MAX_SAFE_INTEGER
) {
return BigInt(val);
} else {
return parseInt(val);
}
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_TIME2:
return val;
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_TIMESTAMP2:
case MYSQL_TYPE_DATETIME2:
return new Date(val);
default:
return val;
}
}

View File

@ -0,0 +1,175 @@
// Loaded from https://deno.land/x/mongo@v0.20.0/src/collection/collection.ts
import { Bson } from "../../deps.ts";
import { WireProtocol } from "../protocol/mod.ts";
import {
CountOptions,
DeleteOptions,
DistinctOptions,
Document,
DropOptions,
FindOptions,
InsertOptions,
UpdateOptions,
} from "../types.ts";
import { FindCursor } from "./commands/find.ts";
import { AggregateCursor } from "./commands/aggregate.ts";
import { update } from "./commands/update.ts";
export class Collection<T> {
#protocol: WireProtocol;
#dbName: string;
constructor(protocol: WireProtocol, dbName: string, readonly name: string) {
this.#protocol = protocol;
this.#dbName = dbName;
}
find(filter?: Document, options?: FindOptions): FindCursor<T> {
return new FindCursor<T>({
filter,
protocol: this.#protocol,
collectionName: this.name,
dbName: this.#dbName,
options: options ?? {},
});
}
async findOne(
filter?: Document,
options?: FindOptions,
): Promise<T | undefined> {
const cursor = this.find(filter, options);
return await cursor.next();
}
async count(filter?: Document, options?: CountOptions): Promise<number> {
const res = await this.#protocol.commandSingle(this.#dbName, {
count: this.name,
query: filter,
...options,
});
const { n, ok } = res;
if (ok === 1) {
return n;
} else {
return 0;
}
}
async insertOne(doc: Document, options?: InsertOptions) {
const { insertedIds } = await this.insertMany([doc], options);
return insertedIds[0];
}
async insert(docs: Document | Document[], options?: InsertOptions) {
docs = Array.isArray(docs) ? docs : [docs];
return this.insertMany(docs as Document[], options);
}
async insertMany(
docs: Document[],
options?: InsertOptions,
): Promise<{ insertedIds: Document[]; insertedCount: number }> {
const insertedIds = docs.map((doc) => {
if (!doc._id) {
doc._id = new Bson.ObjectID();
}
return doc._id;
});
const res = await this.#protocol.commandSingle(this.#dbName, {
insert: this.name,
documents: docs,
ordered: options?.ordered ?? true,
writeConcern: options?.writeConcern,
bypassDocumentValidation: options?.bypassDocumentValidation,
comment: options?.comment,
});
const { writeErrors } = res;
if (writeErrors) {
const [{ errmsg }] = writeErrors;
throw new Error(errmsg);
}
return {
insertedIds,
insertedCount: res.n,
};
}
async updateOne(filter: Document, update: Document, options?: UpdateOptions) {
const {
upsertedIds = [],
upsertedCount,
matchedCount,
modifiedCount,
} = await this.updateMany(filter, update, {
...options,
multi: false,
});
return {
upsertedId: upsertedIds ? upsertedIds[0] : undefined,
upsertedCount,
matchedCount,
modifiedCount,
};
}
async updateMany(filter: Document, doc: Document, options?: UpdateOptions) {
return await update(this.#protocol, this.#dbName, this.name, filter, doc, {
...options,
multi: options?.multi ?? true,
});
}
async deleteMany(filter: Document, options?: DeleteOptions): Promise<number> {
const res = await this.#protocol.commandSingle(this.#dbName, {
delete: this.name,
deletes: [
{
q: filter,
limit: options?.limit ?? 0,
collation: options?.collation,
hint: options?.hint,
comment: options?.comment,
},
],
ordered: options?.ordered ?? true,
writeConcern: options?.writeConcern,
});
return res.n;
}
delete = this.deleteMany;
async deleteOne(filter: Document, options?: DeleteOptions) {
return this.delete(filter, { ...options, limit: 1 });
}
async drop(options?: DropOptions): Promise<void> {
const res = await this.#protocol.commandSingle(this.#dbName, {
drop: this.name,
...options,
});
}
async distinct(key: string, query?: Document, options?: DistinctOptions) {
const { values } = await this.#protocol.commandSingle(this.#dbName, {
distinct: this.name,
key,
query,
...options,
});
return values;
}
aggregate(pipeline: Document[], options?: any): AggregateCursor<T> {
return new AggregateCursor<T>({
pipeline,
protocol: this.#protocol,
dbName: this.#dbName,
collectionName: this.name,
options,
});
}
}

View File

@ -0,0 +1,33 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/lensProp.js
import _curry1 from './internal/_curry1.js';
import assoc from './assoc.js';
import lens from './lens.js';
import prop from './prop.js';
/**
* Returns a lens whose focus is the specified property.
*
* @func
* @memberOf R
* @since v0.14.0
* @category Object
* @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s
* @sig String -> Lens s a
* @param {String} k
* @return {Lens}
* @see R.view, R.set, R.over
* @example
*
* const xLens = R.lensProp('x');
*
* R.view(xLens, {x: 1, y: 2}); //=> 1
* R.set(xLens, 4, {x: 1, y: 2}); //=> {x: 4, y: 2}
* R.over(xLens, R.negate, {x: 1, y: 2}); //=> {x: -1, y: 2}
*/
var lensProp = _curry1(function lensProp(k) {
return lens(prop(k), assoc(k));
});
export default lensProp;

View File

@ -0,0 +1,104 @@
// Loaded from https://deno.land/std@0.78.0/encoding/_yaml/schema.ts
// Ported from js-yaml v3.13.1:
// https://github.com/nodeca/js-yaml/commit/665aadda42349dcae869f12040d9b10ef18d12da
// Copyright 2011-2015 by Vitaly Puzrin. All rights reserved. MIT license.
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { YAMLError } from "./error.ts";
import type { KindType, Type } from "./type.ts";
import type { Any, ArrayObject } from "./utils.ts";
function compileList(
schema: Schema,
name: "implicit" | "explicit",
result: Type[],
): Type[] {
const exclude: number[] = [];
for (const includedSchema of schema.include) {
result = compileList(includedSchema, name, result);
}
for (const currentType of schema[name]) {
for (
let previousIndex = 0;
previousIndex < result.length;
previousIndex++
) {
const previousType = result[previousIndex];
if (
previousType.tag === currentType.tag &&
previousType.kind === currentType.kind
) {
exclude.push(previousIndex);
}
}
result.push(currentType);
}
return result.filter((type, index): unknown => !exclude.includes(index));
}
export type TypeMap = { [k in KindType | "fallback"]: ArrayObject<Type> };
function compileMap(...typesList: Type[][]): TypeMap {
const result: TypeMap = {
fallback: {},
mapping: {},
scalar: {},
sequence: {},
};
for (const types of typesList) {
for (const type of types) {
if (type.kind !== null) {
result[type.kind][type.tag] = result["fallback"][type.tag] = type;
}
}
}
return result;
}
export class Schema implements SchemaDefinition {
public static SCHEMA_DEFAULT?: Schema;
public implicit: Type[];
public explicit: Type[];
public include: Schema[];
public compiledImplicit: Type[];
public compiledExplicit: Type[];
public compiledTypeMap: TypeMap;
constructor(definition: SchemaDefinition) {
this.explicit = definition.explicit || [];
this.implicit = definition.implicit || [];
this.include = definition.include || [];
for (const type of this.implicit) {
if (type.loadKind && type.loadKind !== "scalar") {
throw new YAMLError(
// eslint-disable-next-line max-len
"There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.",
);
}
}
this.compiledImplicit = compileList(this, "implicit", []);
this.compiledExplicit = compileList(this, "explicit", []);
this.compiledTypeMap = compileMap(
this.compiledImplicit,
this.compiledExplicit,
);
}
public static create(): void {}
}
export interface SchemaDefinition {
implicit?: Any[];
explicit?: Type[];
include?: Schema[];
}

View File

@ -0,0 +1,42 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/pipe.js
import _arity from './internal/_arity.js';
import _pipe from './internal/_pipe.js';
import reduce from './reduce.js';
import tail from './tail.js';
/**
* Performs left-to-right function composition. The first argument may have
* any arity; the remaining arguments must be unary.
*
* In some libraries this function is named `sequence`.
*
* **Note:** The result of pipe is not automatically curried.
*
* @func
* @memberOf R
* @since v0.1.0
* @category Function
* @sig (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)
* @param {...Function} functions
* @return {Function}
* @see R.compose
* @example
*
* const f = R.pipe(Math.pow, R.negate, R.inc);
*
* f(3, 4); // -(3^4) + 1
* @symb R.pipe(f, g, h)(a, b) = h(g(f(a, b)))
* @symb R.pipe(f, g, h)(a)(b) = h(g(f(a)))(b)
*/
export default function pipe() {
if (arguments.length === 0) {
throw new Error('pipe requires at least one argument');
}
return _arity(
arguments[0].length,
reduce(_pipe, arguments[0], tail(arguments))
);
}

View File

@ -0,0 +1,192 @@
// Loaded from https://deno.land/std/log/logger.ts
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
import { getLevelByName, getLevelName, LogLevels } from "./levels.ts";
import type { LevelName } from "./levels.ts";
import type { BaseHandler } from "./handlers.ts";
// deno-lint-ignore no-explicit-any
export type GenericFunction = (...args: any[]) => any;
export interface LogRecordOptions {
msg: string;
args: unknown[];
level: number;
loggerName: string;
}
export class LogRecord {
readonly msg: string;
#args: unknown[];
#datetime: Date;
readonly level: number;
readonly levelName: string;
readonly loggerName: string;
constructor(options: LogRecordOptions) {
this.msg = options.msg;
this.#args = [...options.args];
this.level = options.level;
this.loggerName = options.loggerName;
this.#datetime = new Date();
this.levelName = getLevelName(options.level);
}
get args(): unknown[] {
return [...this.#args];
}
get datetime(): Date {
return new Date(this.#datetime.getTime());
}
}
export interface LoggerOptions {
handlers?: BaseHandler[];
}
export class Logger {
#level: LogLevels;
#handlers: BaseHandler[];
readonly #loggerName: string;
constructor(
loggerName: string,
levelName: LevelName,
options: LoggerOptions = {},
) {
this.#loggerName = loggerName;
this.#level = getLevelByName(levelName);
this.#handlers = options.handlers || [];
}
get level(): LogLevels {
return this.#level;
}
set level(level: LogLevels) {
this.#level = level;
}
get levelName(): LevelName {
return getLevelName(this.#level);
}
set levelName(levelName: LevelName) {
this.#level = getLevelByName(levelName);
}
get loggerName(): string {
return this.#loggerName;
}
set handlers(hndls: BaseHandler[]) {
this.#handlers = hndls;
}
get handlers(): BaseHandler[] {
return this.#handlers;
}
/** If the level of the logger is greater than the level to log, then nothing
* is logged, otherwise a log record is passed to each log handler. `msg` data
* passed in is returned. If a function is passed in, it is only evaluated
* if the msg will be logged and the return value will be the result of the
* function, not the function itself, unless the function isn't called, in which
* case undefined is returned. All types are coerced to strings for logging.
*/
private _log<T>(
level: number,
msg: (T extends GenericFunction ? never : T) | (() => T),
...args: unknown[]
): T | undefined {
if (this.level > level) {
return msg instanceof Function ? undefined : msg;
}
let fnResult: T | undefined;
let logMessage: string;
if (msg instanceof Function) {
fnResult = msg();
logMessage = this.asString(fnResult);
} else {
logMessage = this.asString(msg);
}
const record: LogRecord = new LogRecord({
msg: logMessage,
args: args,
level: level,
loggerName: this.loggerName,
});
this.#handlers.forEach((handler): void => {
handler.handle(record);
});
return msg instanceof Function ? fnResult : msg;
}
asString(data: unknown): string {
if (typeof data === "string") {
return data;
} else if (
data === null ||
typeof data === "number" ||
typeof data === "bigint" ||
typeof data === "boolean" ||
typeof data === "undefined" ||
typeof data === "symbol"
) {
return String(data);
} else if (data instanceof Error) {
return data.stack!;
} else if (typeof data === "object") {
return JSON.stringify(data);
}
return "undefined";
}
debug<T>(msg: () => T, ...args: unknown[]): T | undefined;
debug<T>(msg: T extends GenericFunction ? never : T, ...args: unknown[]): T;
debug<T>(
msg: (T extends GenericFunction ? never : T) | (() => T),
...args: unknown[]
): T | undefined {
return this._log(LogLevels.DEBUG, msg, ...args);
}
info<T>(msg: () => T, ...args: unknown[]): T | undefined;
info<T>(msg: T extends GenericFunction ? never : T, ...args: unknown[]): T;
info<T>(
msg: (T extends GenericFunction ? never : T) | (() => T),
...args: unknown[]
): T | undefined {
return this._log(LogLevels.INFO, msg, ...args);
}
warning<T>(msg: () => T, ...args: unknown[]): T | undefined;
warning<T>(msg: T extends GenericFunction ? never : T, ...args: unknown[]): T;
warning<T>(
msg: (T extends GenericFunction ? never : T) | (() => T),
...args: unknown[]
): T | undefined {
return this._log(LogLevels.WARNING, msg, ...args);
}
error<T>(msg: () => T, ...args: unknown[]): T | undefined;
error<T>(msg: T extends GenericFunction ? never : T, ...args: unknown[]): T;
error<T>(
msg: (T extends GenericFunction ? never : T) | (() => T),
...args: unknown[]
): T | undefined {
return this._log(LogLevels.ERROR, msg, ...args);
}
critical<T>(msg: () => T, ...args: unknown[]): T | undefined;
critical<T>(
msg: T extends GenericFunction ? never : T,
...args: unknown[]
): T;
critical<T>(
msg: (T extends GenericFunction ? never : T) | (() => T),
...args: unknown[]
): T | undefined {
return this._log(LogLevels.CRITICAL, msg, ...args);
}
}

View File

@ -0,0 +1,23 @@
// Loaded from https://deno.land/std@0.80.0/encoding/_yaml/error.ts
// Ported from js-yaml v3.13.1:
// https://github.com/nodeca/js-yaml/commit/665aadda42349dcae869f12040d9b10ef18d12da
// Copyright 2011-2015 by Vitaly Puzrin. All rights reserved. MIT license.
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import type { Mark } from "./mark.ts";
export class YAMLError extends Error {
constructor(
message = "(unknown reason)",
protected mark: Mark | string = "",
) {
super(`${message} ${mark}`);
this.name = this.constructor.name;
}
public toString(_compact: boolean): string {
return `${this.name}: ${this.message} ${this.mark}`;
}
}

View File

@ -0,0 +1,87 @@
// Loaded from https://deno.land/std@0.73.0/io/ioutil.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import type { BufReader } from "./bufio.ts";
type Reader = Deno.Reader;
type Writer = Deno.Writer;
import { assert } from "../_util/assert.ts";
const DEFAULT_BUFFER_SIZE = 32 * 1024;
/** copy N size at the most.
* If read size is lesser than N, then returns nread
* */
export async function copyN(
r: Reader,
dest: Writer,
size: number,
): Promise<number> {
let bytesRead = 0;
let buf = new Uint8Array(DEFAULT_BUFFER_SIZE);
while (bytesRead < size) {
if (size - bytesRead < DEFAULT_BUFFER_SIZE) {
buf = new Uint8Array(size - bytesRead);
}
const result = await r.read(buf);
const nread = result ?? 0;
bytesRead += nread;
if (nread > 0) {
let n = 0;
while (n < nread) {
n += await dest.write(buf.slice(n, nread));
}
assert(n === nread, "could not write");
}
if (result === null) {
break;
}
}
return bytesRead;
}
/** Read big endian 16bit short from BufReader */
export async function readShort(buf: BufReader): Promise<number | null> {
const high = await buf.readByte();
if (high === null) return null;
const low = await buf.readByte();
if (low === null) throw new Deno.errors.UnexpectedEof();
return (high << 8) | low;
}
/** Read big endian 32bit integer from BufReader */
export async function readInt(buf: BufReader): Promise<number | null> {
const high = await readShort(buf);
if (high === null) return null;
const low = await readShort(buf);
if (low === null) throw new Deno.errors.UnexpectedEof();
return (high << 16) | low;
}
const MAX_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER);
/** Read big endian 64bit long from BufReader */
export async function readLong(buf: BufReader): Promise<number | null> {
const high = await readInt(buf);
if (high === null) return null;
const low = await readInt(buf);
if (low === null) throw new Deno.errors.UnexpectedEof();
const big = (BigInt(high) << 32n) | BigInt(low);
// We probably should provide a similar API that returns BigInt values.
if (big > MAX_SAFE_INTEGER) {
throw new RangeError(
"Long value too big to be represented as a JavaScript number.",
);
}
return Number(big);
}
/** Slice number into 64bit big endian byte array */
export function sliceLongToBytes(d: number, dest = new Array(8)): number[] {
let big = BigInt(d);
for (let i = 0; i < 8; i++) {
dest[7 - i] = Number(big & 0xffn);
big >>= 8n;
}
return dest;
}

View File

@ -0,0 +1,353 @@
// Loaded from https://deno.land/x/oak@v6.3.1/cookies.ts
// Copyright 2018-2020 the oak authors. All rights reserved. MIT license.
// This was heavily influenced by
// [cookies](https://github.com/pillarjs/cookies/blob/master/index.js)
import type { KeyStack } from "./keyStack.ts";
import type { Request } from "./request.ts";
import type { Response } from "./response.ts";
export interface CookiesOptions {
keys?: KeyStack;
secure?: boolean;
}
export interface CookiesGetOptions {
signed?: boolean;
}
export interface CookiesSetDeleteOptions {
domain?: string;
expires?: Date;
httpOnly?: boolean;
maxAge?: number;
overwrite?: boolean;
path?: string;
secure?: boolean;
sameSite?: "strict" | "lax" | "none" | boolean;
signed?: boolean;
}
type CookieAttributes = CookiesSetDeleteOptions;
const matchCache: Record<string, RegExp> = {};
// deno-lint-ignore no-control-regex
const FIELD_CONTENT_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
const KEY_REGEXP = /(?:^|;) *([^=]*)=[^;]*/g;
const SAME_SITE_REGEXP = /^(?:lax|none|strict)$/i;
function getPattern(name: string): RegExp {
if (name in matchCache) {
return matchCache[name];
}
return matchCache[name] = new RegExp(
`(?:^|;) *${name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")}=([^;]*)`,
);
}
function pushCookie(headers: string[], cookie: Cookie): void {
if (cookie.overwrite) {
for (let i = headers.length - 1; i >= 0; i--) {
if (headers[i].indexOf(`${cookie.name}=`) === 0) {
headers.splice(i, 1);
}
}
}
headers.push(cookie.toHeader());
}
function validateCookieProperty(
key: string,
value: string | undefined | null,
): void {
if (value && !FIELD_CONTENT_REGEXP.test(value)) {
throw new TypeError(`The ${key} of the cookie (${value}) is invalid.`);
}
}
class Cookie implements CookieAttributes {
domain?: string;
expires?: Date;
httpOnly = true;
maxAge?: number;
name: string;
overwrite = false;
path = "/";
sameSite: "strict" | "lax" | "none" | boolean = false;
secure = false;
signed?: boolean;
value: string;
/** A logical representation of a cookie, used to internally manage the
* cookie instances. */
constructor(
name: string,
value: string | null,
attributes: CookieAttributes,
) {
validateCookieProperty("name", name);
validateCookieProperty("value", value);
this.name = name;
this.value = value ?? "";
Object.assign(this, attributes);
if (!this.value) {
this.expires = new Date(0);
this.maxAge = undefined;
}
validateCookieProperty("path", this.path);
validateCookieProperty("domain", this.domain);
if (
this.sameSite && typeof this.sameSite === "string" &&
!SAME_SITE_REGEXP.test(this.sameSite)
) {
throw new TypeError(
`The sameSite of the cookie ("${this.sameSite}") is invalid.`,
);
}
}
toHeader(): string {
let header = this.toString();
if (this.maxAge) {
this.expires = new Date(Date.now() + (this.maxAge * 1000));
}
if (this.path) {
header += `; path=${this.path}`;
}
if (this.expires) {
header += `; expires=${this.expires.toUTCString()}`;
}
if (this.domain) {
header += `; domain=${this.domain}`;
}
if (this.sameSite) {
header += `; samesite=${
this.sameSite === true ? "strict" : this.sameSite.toLowerCase()
}`;
}
if (this.secure) {
header += "; secure";
}
if (this.httpOnly) {
header += "; httponly";
}
return header;
}
toString(): string {
return `${this.name}=${this.value}`;
}
}
/** An interface which allows setting and accessing cookies related to both the
* current request and response. */
export class Cookies {
#cookieKeys?: string[];
#keys?: KeyStack;
#request: Request;
#response: Response;
#secure?: boolean;
#requestKeys = (): string[] => {
if (this.#cookieKeys) {
return this.#cookieKeys;
}
const result = this.#cookieKeys = [] as string[];
const header = this.#request.headers.get("cookie");
if (!header) {
return result;
}
let matches: RegExpExecArray | null;
while ((matches = KEY_REGEXP.exec(header))) {
const [, key] = matches;
result.push(key);
}
return result;
};
constructor(
request: Request,
response: Response,
options: CookiesOptions = {},
) {
const { keys, secure } = options;
this.#keys = keys;
this.#request = request;
this.#response = response;
this.#secure = secure;
}
/** Set a cookie to be deleted in the response. This is a "shortcut" to
* `.set(name, null, options?)`. */
delete(name: string, options: CookiesSetDeleteOptions = {}): boolean {
this.set(name, null, options);
return true;
}
/** Iterate over the request's cookies, yielding up a tuple containing the
* key and the value.
*
* If there are keys set on the application, only keys and values that are
* properly signed will be returned. */
*entries(): IterableIterator<[string, string]> {
const keys = this.#requestKeys();
for (const key of keys) {
const value = this.get(key);
if (value) {
yield [key, value];
}
}
}
forEach(
callback: (key: string, value: string, cookies: this) => void,
// deno-lint-ignore no-explicit-any
thisArg: any = null,
): void {
const keys = this.#requestKeys();
for (const key of keys) {
const value = this.get(key);
if (value) {
callback.call(thisArg, key, value, this);
}
}
}
/** Get the value of a cookie from the request.
*
* If the cookie is signed, and the signature is invalid, the cookie will
* be set to be deleted in the the response. If the signature uses an "old"
* key, the cookie will be re-signed with the current key and be added to the
* response to be updated. */
get(name: string, options: CookiesGetOptions = {}): string | undefined {
const signed = options.signed ?? !!this.#keys;
const nameSig = `${name}.sig`;
const header = this.#request.headers.get("cookie");
if (!header) {
return;
}
const match = header.match(getPattern(name));
if (!match) {
return;
}
const [, value] = match;
if (!signed) {
return value;
}
const digest = this.get(nameSig, { signed: false });
if (!digest) {
return;
}
const data = `${name}=${value}`;
if (!this.#keys) {
throw new TypeError("keys required for signed cookies");
}
const index = this.#keys.indexOf(data, digest);
if (index < 0) {
this.delete(nameSig, { path: "/", signed: false });
} else {
if (index) {
// the key has "aged" and needs to be re-signed
this.set(nameSig, this.#keys.sign(data), { signed: false });
}
return value;
}
}
/** Iterate over the request's cookies, yielding up the keys.
*
* If there are keys set on the application, only the keys that are properly
* signed will be returned. */
*keys(): IterableIterator<string> {
const keys = this.#requestKeys();
for (const key of keys) {
const value = this.get(key);
if (value) {
yield key;
}
}
}
/** Set a cookie in the response.
*
* If there are keys set in the application, cookies will be automatically
* signed, unless overridden by the set options. Cookies can be deleted by
* setting the value to `null`. */
set(
name: string,
value: string | null,
options: CookiesSetDeleteOptions = {},
): this {
const request = this.#request;
const response = this.#response;
let headers = response.headers.get("Set-Cookie") ?? [] as string[];
if (typeof headers === "string") {
headers = [headers];
}
const secure = this.#secure !== undefined ? this.#secure : request.secure;
const signed = options.signed ?? !!this.#keys;
if (!secure && options.secure) {
throw new TypeError(
"Cannot send secure cookie over unencrypted connection.",
);
}
const cookie = new Cookie(name, value, options);
cookie.secure = options.secure ?? secure;
pushCookie(headers, cookie);
if (signed) {
if (!this.#keys) {
throw new TypeError(".keys required for signed cookies.");
}
cookie.value = this.#keys.sign(cookie.toString());
cookie.name += ".sig";
pushCookie(headers, cookie);
}
for (const header of headers) {
response.headers.append("Set-Cookie", header);
}
return this;
}
/** Iterate over the request's cookies, yielding up each value.
*
* If there are keys set on the application, only the values that are
* properly signed will be returned. */
*values(): IterableIterator<string> {
const keys = this.#requestKeys();
for (const key of keys) {
const value = this.get(key);
if (value) {
yield value;
}
}
}
/** Iterate over the request's cookies, yielding up a tuple containing the
* key and the value.
*
* If there are keys set on the application, only keys and values that are
* properly signed will be returned. */
*[Symbol.iterator](): IterableIterator<[string, string]> {
const keys = this.#requestKeys();
for (const key of keys) {
const value = this.get(key);
if (value) {
yield [key, value];
}
}
}
}

View File

@ -0,0 +1,43 @@
// Loaded from https://deno.land/x/god_crypto@v0.2.0/src/eme_oaep.ts
import { createHash } from "https://deno.land/std/hash/mod.ts";
import { mgf1 } from "./primitives.ts";
import { concat, xor, random_bytes } from "./helper.ts";
/**
* https://tools.ietf.org/html/rfc3447#page-10
*
* @param label
* @param m
* @param k
* @param algorithm
*/
export function eme_oaep_encode(label: Uint8Array, m: Uint8Array, k: number, algorithm: "sha1" | "sha256"): Uint8Array {
const labelHash = new Uint8Array(createHash(algorithm).update(label).digest());
const ps = new Uint8Array(k - labelHash.length * 2 - 2 - m.length);
const db = concat(labelHash, ps, [0x01], m);
const seed = random_bytes(labelHash.length);
const dbMask = mgf1(seed, k - labelHash.length - 1, algorithm);
const maskedDb = xor(db, dbMask);
const seedMask = mgf1(maskedDb, labelHash.length, algorithm);
const maskedSeed = xor(seed, seedMask);
return concat([0x00], maskedSeed, maskedDb);
}
export function eme_oaep_decode(label: Uint8Array, c: Uint8Array, k: number, algorithm: "sha1" | "sha256"): Uint8Array {
const labelHash = new Uint8Array(createHash(algorithm).update(label).digest());
const maskedSeed = c.slice(1, 1 + labelHash.length);
const maskedDb = c.slice(1 + labelHash.length);
const seedMask = mgf1(maskedDb, labelHash.length, algorithm);
const seed = xor(maskedSeed, seedMask);
const dbMask = mgf1(seed, k - labelHash.length - 1, algorithm);
const db = xor(maskedDb, dbMask);
let ptr = labelHash.length;
while(ptr < db.length && db[ptr] === 0) ptr++;
return db.slice(ptr + 1);
}

View File

@ -0,0 +1,51 @@
// Loaded from https://deno.land/std@0.84.0/path/_constants.ts
// Copyright the Browserify authors. MIT License.
// Ported from https://github.com/browserify/path-browserify/
// This module is browser compatible.
// Alphabet chars.
export const CHAR_UPPERCASE_A = 65; /* A */
export const CHAR_LOWERCASE_A = 97; /* a */
export const CHAR_UPPERCASE_Z = 90; /* Z */
export const CHAR_LOWERCASE_Z = 122; /* z */
// Non-alphabetic chars.
export const CHAR_DOT = 46; /* . */
export const CHAR_FORWARD_SLASH = 47; /* / */
export const CHAR_BACKWARD_SLASH = 92; /* \ */
export const CHAR_VERTICAL_LINE = 124; /* | */
export const CHAR_COLON = 58; /* : */
export const CHAR_QUESTION_MARK = 63; /* ? */
export const CHAR_UNDERSCORE = 95; /* _ */
export const CHAR_LINE_FEED = 10; /* \n */
export const CHAR_CARRIAGE_RETURN = 13; /* \r */
export const CHAR_TAB = 9; /* \t */
export const CHAR_FORM_FEED = 12; /* \f */
export const CHAR_EXCLAMATION_MARK = 33; /* ! */
export const CHAR_HASH = 35; /* # */
export const CHAR_SPACE = 32; /* */
export const CHAR_NO_BREAK_SPACE = 160; /* \u00A0 */
export const CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279; /* \uFEFF */
export const CHAR_LEFT_SQUARE_BRACKET = 91; /* [ */
export const CHAR_RIGHT_SQUARE_BRACKET = 93; /* ] */
export const CHAR_LEFT_ANGLE_BRACKET = 60; /* < */
export const CHAR_RIGHT_ANGLE_BRACKET = 62; /* > */
export const CHAR_LEFT_CURLY_BRACKET = 123; /* { */
export const CHAR_RIGHT_CURLY_BRACKET = 125; /* } */
export const CHAR_HYPHEN_MINUS = 45; /* - */
export const CHAR_PLUS = 43; /* + */
export const CHAR_DOUBLE_QUOTE = 34; /* " */
export const CHAR_SINGLE_QUOTE = 39; /* ' */
export const CHAR_PERCENT = 37; /* % */
export const CHAR_SEMICOLON = 59; /* ; */
export const CHAR_CIRCUMFLEX_ACCENT = 94; /* ^ */
export const CHAR_GRAVE_ACCENT = 96; /* ` */
export const CHAR_AT = 64; /* @ */
export const CHAR_AMPERSAND = 38; /* & */
export const CHAR_EQUAL = 61; /* = */
// Digits
export const CHAR_0 = 48; /* 0 */
export const CHAR_9 = 57; /* 9 */

View File

@ -0,0 +1,104 @@
// Loaded from https://deno.land/std@0.80.0/encoding/_yaml/schema.ts
// Ported from js-yaml v3.13.1:
// https://github.com/nodeca/js-yaml/commit/665aadda42349dcae869f12040d9b10ef18d12da
// Copyright 2011-2015 by Vitaly Puzrin. All rights reserved. MIT license.
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { YAMLError } from "./error.ts";
import type { KindType, Type } from "./type.ts";
import type { Any, ArrayObject } from "./utils.ts";
function compileList(
schema: Schema,
name: "implicit" | "explicit",
result: Type[],
): Type[] {
const exclude: number[] = [];
for (const includedSchema of schema.include) {
result = compileList(includedSchema, name, result);
}
for (const currentType of schema[name]) {
for (
let previousIndex = 0;
previousIndex < result.length;
previousIndex++
) {
const previousType = result[previousIndex];
if (
previousType.tag === currentType.tag &&
previousType.kind === currentType.kind
) {
exclude.push(previousIndex);
}
}
result.push(currentType);
}
return result.filter((type, index): unknown => !exclude.includes(index));
}
export type TypeMap = { [k in KindType | "fallback"]: ArrayObject<Type> };
function compileMap(...typesList: Type[][]): TypeMap {
const result: TypeMap = {
fallback: {},
mapping: {},
scalar: {},
sequence: {},
};
for (const types of typesList) {
for (const type of types) {
if (type.kind !== null) {
result[type.kind][type.tag] = result["fallback"][type.tag] = type;
}
}
}
return result;
}
export class Schema implements SchemaDefinition {
public static SCHEMA_DEFAULT?: Schema;
public implicit: Type[];
public explicit: Type[];
public include: Schema[];
public compiledImplicit: Type[];
public compiledExplicit: Type[];
public compiledTypeMap: TypeMap;
constructor(definition: SchemaDefinition) {
this.explicit = definition.explicit || [];
this.implicit = definition.implicit || [];
this.include = definition.include || [];
for (const type of this.implicit) {
if (type.loadKind && type.loadKind !== "scalar") {
throw new YAMLError(
// eslint-disable-next-line max-len
"There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.",
);
}
}
this.compiledImplicit = compileList(this, "implicit", []);
this.compiledExplicit = compileList(this, "explicit", []);
this.compiledTypeMap = compileMap(
this.compiledImplicit,
this.compiledExplicit,
);
}
public static create(): void {}
}
export interface SchemaDefinition {
implicit?: Any[];
explicit?: Type[];
include?: Schema[];
}

View File

@ -0,0 +1,62 @@
// Loaded from https://deno.land/std@0.77.0/log/levels.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
/** Get log level numeric values through enum constants
*/
export enum LogLevels {
NOTSET = 0,
DEBUG = 10,
INFO = 20,
WARNING = 30,
ERROR = 40,
CRITICAL = 50,
}
/** Permitted log level names */
export const LogLevelNames = Object.keys(LogLevels).filter((key) =>
isNaN(Number(key))
);
/** Union of valid log level strings */
export type LevelName = keyof typeof LogLevels;
const byLevel: Record<string, LevelName> = {
[String(LogLevels.NOTSET)]: "NOTSET",
[String(LogLevels.DEBUG)]: "DEBUG",
[String(LogLevels.INFO)]: "INFO",
[String(LogLevels.WARNING)]: "WARNING",
[String(LogLevels.ERROR)]: "ERROR",
[String(LogLevels.CRITICAL)]: "CRITICAL",
};
/** Returns the numeric log level associated with the passed,
* stringy log level name.
*/
export function getLevelByName(name: LevelName): number {
switch (name) {
case "NOTSET":
return LogLevels.NOTSET;
case "DEBUG":
return LogLevels.DEBUG;
case "INFO":
return LogLevels.INFO;
case "WARNING":
return LogLevels.WARNING;
case "ERROR":
return LogLevels.ERROR;
case "CRITICAL":
return LogLevels.CRITICAL;
default:
throw new Error(`no log level found for "${name}"`);
}
}
/** Returns the stringy log level name provided the numeric log level */
export function getLevelName(level: number): LevelName {
const levelName = byLevel[level];
if (levelName) {
return levelName;
}
throw new Error(`no level name found for level: ${level}`);
}

View File

@ -0,0 +1,49 @@
// Loaded from https://deno.land/std@0.81.0/async/pool.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
/**
* pooledMap transforms values from an (async) iterable into another async
* iterable. The transforms are done concurrently, with a max concurrency
* defined by the poolLimit.
*
* @param poolLimit The maximum count of items being processed concurrently.
* @param array The input array for mapping.
* @param iteratorFn The function to call for every item of the array.
*/
export function pooledMap<T, R>(
poolLimit: number,
array: Iterable<T> | AsyncIterable<T>,
iteratorFn: (data: T) => Promise<R>,
): AsyncIterableIterator<R> {
// Create the async iterable that is returned from this function.
const res = new TransformStream<Promise<R>, R>({
async transform(
p: Promise<R>,
controller: TransformStreamDefaultController<R>,
): Promise<void> {
controller.enqueue(await p);
},
});
// Start processing items from the iterator
(async (): Promise<void> => {
const writer = res.writable.getWriter();
const executing: Array<Promise<unknown>> = [];
for await (const item of array) {
const p = Promise.resolve().then(() => iteratorFn(item));
writer.write(p);
const e: Promise<unknown> = p.then(() =>
executing.splice(executing.indexOf(e), 1)
);
executing.push(e);
if (executing.length >= poolLimit) {
await Promise.race(executing);
}
}
// Wait until all ongoing events have processed, then close the writer.
await Promise.all(executing);
writer.close();
})();
return res.readable.getIterator();
}

View File

@ -0,0 +1,6 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/internal/_isObject.js
export default function _isObject(x) {
return Object.prototype.toString.call(x) === '[object Object]';
}

View File

@ -0,0 +1,34 @@
// Loaded from https://deno.land/x/graphql_deno@v15.0.0/lib/utilities/assertValidName.js
import devAssert from '../jsutils/devAssert.js';
import { GraphQLError } from '../error/GraphQLError.js';
const NAME_RX = /^[_a-zA-Z][_a-zA-Z0-9]*$/;
/**
* Upholds the spec rules about naming.
*/
export function assertValidName(name) {
const error = isValidNameError(name);
if (error) {
throw error;
}
return name;
}
/**
* Returns an Error if a name is invalid.
*/
export function isValidNameError(name) {
devAssert(typeof name === 'string', 'Expected name to be a string.');
if (name.length > 1 && name[0] === '_' && name[1] === '_') {
return new GraphQLError(`Name "${name}" must not begin with "__", which is reserved by GraphQL introspection.`);
}
if (!NAME_RX.test(name)) {
return new GraphQLError(`Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "${name}" does not.`);
}
}

View File

@ -0,0 +1,10 @@
// Loaded from https://deno.land/std@0.67.0/path/separator.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
/** This module is browser compatible. */
import { isWindows } from "./_constants.ts";
export const SEP = isWindows ? "\\" : "/";
export const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/;

View File

@ -0,0 +1,46 @@
// Loaded from https://deno.land/x/graphql_deno@v15.0.0/lib/validation/rules/NoUnusedVariablesRule.js
import { GraphQLError } from '../../error/GraphQLError.js';
/**
* No unused variables
*
* A GraphQL operation is only valid if all variables defined by an operation
* are used, either directly or within a spread fragment.
*/
export function NoUnusedVariablesRule(context) {
let variableDefs = [];
return {
OperationDefinition: {
enter() {
variableDefs = [];
},
leave(operation) {
const variableNameUsed = Object.create(null);
const usages = context.getRecursiveVariableUsages(operation);
for (const {
node
} of usages) {
variableNameUsed[node.name.value] = true;
}
for (const variableDef of variableDefs) {
const variableName = variableDef.variable.name.value;
if (variableNameUsed[variableName] !== true) {
context.reportError(new GraphQLError(operation.name ? `Variable "$${variableName}" is never used in operation "${operation.name.value}".` : `Variable "$${variableName}" is never used.`, variableDef));
}
}
}
},
VariableDefinition(def) {
variableDefs.push(def);
}
};
}

View File

@ -0,0 +1,33 @@
// Loaded from https://deno.land/std@0.85.0/path/_interface.ts
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
/**
* A parsed path object generated by path.parse() or consumed by path.format().
*/
export interface ParsedPath {
/**
* The root of the path such as '/' or 'c:\'
*/
root: string;
/**
* The full directory path such as '/home/user/dir' or 'c:\path\dir'
*/
dir: string;
/**
* The file name including extension (if any) such as 'index.html'
*/
base: string;
/**
* The file extension (if any) such as '.html'
*/
ext: string;
/**
* The file name without extension (if any) such as 'index'
*/
name: string;
}
export type FormatInputPathObject = Partial<ParsedPath>;

View File

@ -0,0 +1,132 @@
// Loaded from https://deno.land/x/segno@v1.1.0/lib/validations/isTaxID.ts
/**
* An Employer Identification Number (EIN), also known as a Federal Tax Identification Number,
* is used to identify a business entity.
*
* NOTES:
* - Prefix 47 is being reserved for future use
* - Prefixes 26, 27, 45, 46 and 47 were previously assigned by the Philadelphia campus.
*
* See `http://www.irs.gov/Businesses/Small-Businesses-&-Self-Employed/How-EINs-are-Assigned-and-Valid-EIN-Prefixes`
* for more information.
*/
// @ts-ignore allowing typedoc to build
import { assertString } from '../helpers/assertString.ts';
/**
* Campus prefixes according to locales
*/
/**
* @ignore
*/
const campusPrefix = {
'en-US': {
andover: ['10', '12'],
atlanta: ['60', '67'],
austin: ['50', '53'],
brookhaven: [
'01',
'02',
'03',
'04',
'05',
'06',
'11',
'13',
'14',
'16',
'21',
'22',
'23',
'25',
'34',
'51',
'52',
'54',
'55',
'56',
'57',
'58',
'59',
'65',
],
cincinnati: ['30', '32', '35', '36', '37', '38', '61'],
fresno: ['15', '24'],
internet: ['20', '26', '27', '45', '46', '47'],
kansas: ['40', '44'],
memphis: ['94', '95'],
ogden: ['80', '90'],
philadelphia: [
'33',
'39',
'41',
'42',
'43',
'46',
'48',
'62',
'63',
'64',
'66',
'68',
'71',
'72',
'73',
'74',
'75',
'76',
'77',
'81',
'82',
'83',
'84',
'85',
'86',
'87',
'88',
'91',
'92',
'93',
'98',
'99',
],
sba: ['31'],
},
};
/**
* @ignore
*/
const getPrefixes = (locale: string) => {
const prefixes = [];
for (const location in (campusPrefix as any)[locale]) {
if ((campusPrefix as any)[locale].hasOwnProperty(location)) {
prefixes.push(...(campusPrefix as any)[locale][location]);
}
}
prefixes.sort();
return prefixes;
};
// tax id regex formats for various loacles
/**
* @ignore
*/
const taxIdFormat = {
'en-US': /^\d{2}[- ]{0,1}\d{7}$/,
};
export const isTaxID = (str: string, locale = 'en-US') => {
assertString(str);
if (!(taxIdFormat as any)[locale].test(str)) {
return false;
}
return getPrefixes(locale).indexOf(str.substr(0, 2)) !== -1;
};

View File

@ -0,0 +1,72 @@
// Loaded from https://deno.land/std@0.73.0/async/mux_async_iterator.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { Deferred, deferred } from "./deferred.ts";
interface TaggedYieldedValue<T> {
iterator: AsyncIterableIterator<T>;
value: T;
}
/** The MuxAsyncIterator class multiplexes multiple async iterators into a
* single stream. It currently makes an assumption:
* - The final result (the value returned and not yielded from the iterator)
* does not matter; if there is any, it is discarded.
*/
export class MuxAsyncIterator<T> implements AsyncIterable<T> {
private iteratorCount = 0;
private yields: Array<TaggedYieldedValue<T>> = [];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private throws: any[] = [];
private signal: Deferred<void> = deferred();
add(iterator: AsyncIterableIterator<T>): void {
++this.iteratorCount;
this.callIteratorNext(iterator);
}
private async callIteratorNext(
iterator: AsyncIterableIterator<T>,
): Promise<void> {
try {
const { value, done } = await iterator.next();
if (done) {
--this.iteratorCount;
} else {
this.yields.push({ iterator, value });
}
} catch (e) {
this.throws.push(e);
}
this.signal.resolve();
}
async *iterate(): AsyncIterableIterator<T> {
while (this.iteratorCount > 0) {
// Sleep until any of the wrapped iterators yields.
await this.signal;
// Note that while we're looping over `yields`, new items may be added.
for (let i = 0; i < this.yields.length; i++) {
const { iterator, value } = this.yields[i];
yield value;
this.callIteratorNext(iterator);
}
if (this.throws.length) {
for (const e of this.throws) {
throw e;
}
this.throws.length = 0;
}
// Clear the `yields` list and reset the `signal` promise.
this.yields.length = 0;
this.signal = deferred();
}
}
[Symbol.asyncIterator](): AsyncIterableIterator<T> {
return this.iterate();
}
}

View File

@ -0,0 +1,10 @@
// Loaded from https://deno.land/x/segno@v1.1.0/mod.ts
import * as segno from './lib/index.ts';
// exporting all functions
export * from './lib/index.ts';
// exporting functions namespaced to segno
export { segno };

View File

@ -0,0 +1,10 @@
// Loaded from https://deno.land/std@0.80.0/path/separator.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
/** This module is browser compatible. */
import { isWindows } from "../_util/os.ts";
export const SEP = isWindows ? "\\" : "/";
export const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/;

View File

@ -0,0 +1,32 @@
// Loaded from https://deno.land/x/colorlog@v1.0/mod.ts
const reset: String = "\x1b[0m";
const red: String = "\x1b[31m";
const green: String = "\x1b[32m";
const yellow: String = "\x1b[33m";
function error(val: any) {
return (red + val + reset);
}
function success(val: any) {
return (green + val + reset);
}
function warning(val: any) {
return (yellow + val + reset);
}
function errorLog(val: any) {
console.log(red + val + reset);
}
function successLog(val: any) {
console.log(green + val + reset);
}
function warningLog(val: any) {
console.log(yellow + val + reset);
}
export { error, success, warning, errorLog, successLog, warningLog };

View File

@ -0,0 +1,35 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/toPairs.js
import _curry1 from './internal/_curry1.js';
import _has from './internal/_has.js';
/**
* Converts an object into an array of key, value arrays. Only the object's
* own properties are used.
* Note that the order of the output array is not guaranteed to be consistent
* across different JS platforms.
*
* @func
* @memberOf R
* @since v0.4.0
* @category Object
* @sig {String: *} -> [[String,*]]
* @param {Object} obj The object to extract from
* @return {Array} An array of key, value arrays from the object's own properties.
* @see R.fromPairs
* @example
*
* R.toPairs({a: 1, b: 2, c: 3}); //=> [['a', 1], ['b', 2], ['c', 3]]
*/
var toPairs = _curry1(function toPairs(obj) {
var pairs = [];
for (var prop in obj) {
if (_has(prop, obj)) {
pairs[pairs.length] = [prop, obj[prop]];
}
}
return pairs;
});
export default toPairs;

View File

@ -0,0 +1,19 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/internal/_xfilter.js
import _curry2 from './_curry2.js';
import _xfBase from './_xfBase.js';
function XFilter(f, xf) {
this.xf = xf;
this.f = f;
}
XFilter.prototype['@@transducer/init'] = _xfBase.init;
XFilter.prototype['@@transducer/result'] = _xfBase.result;
XFilter.prototype['@@transducer/step'] = function(result, input) {
return this.f(input) ? this.xf['@@transducer/step'](result, input) : result;
};
var _xfilter = _curry2(function _xfilter(f, xf) { return new XFilter(f, xf); });
export default _xfilter;

View File

@ -0,0 +1,37 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/propEq.js
import _curry3 from './internal/_curry3.js';
import prop from './prop.js';
import equals from './equals.js';
/**
* Returns `true` if the specified object property is equal, in
* [`R.equals`](#equals) terms, to the given value; `false` otherwise.
* You can test multiple properties with [`R.whereEq`](#whereEq).
*
* @func
* @memberOf R
* @since v0.1.0
* @category Relation
* @sig String -> a -> Object -> Boolean
* @param {String} name
* @param {*} val
* @param {*} obj
* @return {Boolean}
* @see R.whereEq, R.propSatisfies, R.equals
* @example
*
* const abby = {name: 'Abby', age: 7, hair: 'blond'};
* const fred = {name: 'Fred', age: 12, hair: 'brown'};
* const rusty = {name: 'Rusty', age: 10, hair: 'brown'};
* const alois = {name: 'Alois', age: 15, disposition: 'surly'};
* const kids = [abby, fred, rusty, alois];
* const hasBrownHair = R.propEq('hair', 'brown');
* R.filter(hasBrownHair, kids); //=> [fred, rusty]
*/
var propEq = _curry3(function propEq(name, val, obj) {
return equals(val, prop(name, obj));
});
export default propEq;

View File

@ -0,0 +1,23 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/internal/_xdrop.js
import _curry2 from './_curry2.js';
import _xfBase from './_xfBase.js';
function XDrop(n, xf) {
this.xf = xf;
this.n = n;
}
XDrop.prototype['@@transducer/init'] = _xfBase.init;
XDrop.prototype['@@transducer/result'] = _xfBase.result;
XDrop.prototype['@@transducer/step'] = function(result, input) {
if (this.n > 0) {
this.n -= 1;
return result;
}
return this.xf['@@transducer/step'](result, input);
};
var _xdrop = _curry2(function _xdrop(n, xf) { return new XDrop(n, xf); });
export default _xdrop;

View File

@ -0,0 +1,9 @@
// Loaded from https://deno.land/x/case@v2.1.0/constantCase.ts
import upperCase from "./upperCase.ts";
import snakeCase from "./snakeCase.ts";
export default function constantCase(value: string, locale?: string): string {
return upperCase(snakeCase(value, locale), locale);
}

View File

@ -0,0 +1,57 @@
// Loaded from https://deno.land/x/segno@v1.1.0/lib/validations/isMimeType.ts
/*
Checks if the provided string matches to a correct Media type format (MIME type)
This function only checks is the string format follows the
etablished rules by the according RFC specifications.
This function supports 'charset' in textual media types
(https://tools.ietf.org/html/rfc6657).
This function does not check against all the media types listed
by the IANA (https://www.iana.org/assignments/media-types/media-types.xhtml)
because of lightness purposes : it would require to include
all these MIME types in this librairy, which would weigh it
significantly. This kind of effort maybe is not worth for the use that
this function has in this entire librairy.
More informations in the RFC specifications :
- https://tools.ietf.org/html/rfc2045
- https://tools.ietf.org/html/rfc2046
- https://tools.ietf.org/html/rfc7231#section-3.1.1.1
- https://tools.ietf.org/html/rfc7231#section-3.1.1.5
*/
// @ts-ignore allowing typedoc to build
import { assertString } from '../helpers/assertString.ts';
// Match simple MIME types
// NB :
// Subtype length must not exceed 100 characters.
// This rule does not comply to the RFC specs (what is the max length ?).
/**
* @ignore
*/
const mimeTypeSimple = /^(application|audio|font|image|message|model|multipart|text|video)\/[a-zA-Z0-9\.\-\+]{1,100}$/i; // eslint-disable-line max-len
// Handle "charset" in "text/*"
/**
* @ignore
*/
const mimeTypeText = /^text\/[a-zA-Z0-9\.\-\+]{1,100};\s?charset=("[a-zA-Z0-9\.\-\+\s]{0,70}"|[a-zA-Z0-9\.\-\+]{0,70})(\s?\([a-zA-Z0-9\.\-\+\s]{1,20}\))?$/i; // eslint-disable-line max-len
// Handle "boundary" in "multipart/*"
/**
* @ignore
*/
const mimeTypeMultipart = /^multipart\/[a-zA-Z0-9\.\-\+]{1,100}(;\s?(boundary|charset)=("[a-zA-Z0-9\.\-\+\s]{0,70}"|[a-zA-Z0-9\.\-\+]{0,70})(\s?\([a-zA-Z0-9\.\-\+\s]{1,20}\))?){0,2}$/i; // eslint-disable-line max-len
export const isMimeType = (str: string) => {
assertString(str);
return (
mimeTypeSimple.test(str) ||
mimeTypeText.test(str) ||
mimeTypeMultipart.test(str)
);
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
// Loaded from https://deno.land/std@0.78.0/encoding/_yaml/stringify.ts
// Ported from js-yaml v3.13.1:
// https://github.com/nodeca/js-yaml/commit/665aadda42349dcae869f12040d9b10ef18d12da
// Copyright 2011-2015 by Vitaly Puzrin. All rights reserved. MIT license.
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { dump } from "./dumper/dumper.ts";
import type { DumperStateOptions } from "./dumper/dumper_state.ts";
export type DumpOptions = DumperStateOptions;
/**
* Serializes `object` as a YAML document.
*
* You can disable exceptions by setting the skipInvalid option to true.
*/
export function stringify(
obj: Record<string, unknown>,
options?: DumpOptions,
): string {
return dump(obj, options);
}

View File

@ -0,0 +1,143 @@
// Loaded from https://deno.land/x/graphql_deno@v15.0.0/lib/graphql.js
import isPromise from './jsutils/isPromise.js';
import { parse } from './language/parser.js';
import { validate } from './validation/validate.js';
import { validateSchema } from './type/validate.js';
import { execute } from './execution/execute.js';
/**
* This is the primary entry point function for fulfilling GraphQL operations
* by parsing, validating, and executing a GraphQL document along side a
* GraphQL schema.
*
* More sophisticated GraphQL servers, such as those which persist queries,
* may wish to separate the validation and execution phases to a static time
* tooling step, and a server runtime step.
*
* Accepts either an object with named arguments, or individual arguments:
*
* schema:
* The GraphQL type system to use when validating and executing a query.
* source:
* A GraphQL language formatted string representing the requested operation.
* rootValue:
* The value provided as the first argument to resolver functions on the top
* level type (e.g. the query object type).
* contextValue:
* The context value is provided as an argument to resolver functions after
* field arguments. It is used to pass shared information useful at any point
* during executing this query, for example the currently logged in user and
* connections to databases or other services.
* variableValues:
* A mapping of variable name to runtime value to use for all variables
* defined in the requestString.
* operationName:
* The name of the operation to use if requestString contains multiple
* possible operations. Can be omitted if requestString contains only
* one operation.
* fieldResolver:
* A resolver function to use when one is not provided by the schema.
* If not provided, the default field resolver is used (which looks for a
* value or method on the source value with the field's name).
* typeResolver:
* A type resolver function to use when none is provided by the schema.
* If not provided, the default type resolver is used (which looks for a
* `__typename` field or alternatively calls the `isTypeOf` method).
*/
export function graphql(argsOrSchema, source, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) {
/* eslint-enable no-redeclare */
// Always return a Promise for a consistent API.
return new Promise(resolve => resolve( // Extract arguments from object args if provided.
arguments.length === 1 ? graphqlImpl(argsOrSchema) : graphqlImpl({
schema: argsOrSchema,
source,
rootValue,
contextValue,
variableValues,
operationName,
fieldResolver,
typeResolver
})));
}
/**
* The graphqlSync function also fulfills GraphQL operations by parsing,
* validating, and executing a GraphQL document along side a GraphQL schema.
* However, it guarantees to complete synchronously (or throw an error) assuming
* that all field resolvers are also synchronous.
*/
export function graphqlSync(argsOrSchema, source, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) {
/* eslint-enable no-redeclare */
// Extract arguments from object args if provided.
const result = arguments.length === 1 ? graphqlImpl(argsOrSchema) : graphqlImpl({
schema: argsOrSchema,
source,
rootValue,
contextValue,
variableValues,
operationName,
fieldResolver,
typeResolver
}); // Assert that the execution was synchronous.
if (isPromise(result)) {
throw new Error('GraphQL execution failed to complete synchronously.');
}
return result;
}
function graphqlImpl(args) {
const {
schema,
source,
rootValue,
contextValue,
variableValues,
operationName,
fieldResolver,
typeResolver
} = args; // Validate Schema
const schemaValidationErrors = validateSchema(schema);
if (schemaValidationErrors.length > 0) {
return {
errors: schemaValidationErrors
};
} // Parse
let document;
try {
document = parse(source);
} catch (syntaxError) {
return {
errors: [syntaxError]
};
} // Validate
const validationErrors = validate(schema, document);
if (validationErrors.length > 0) {
return {
errors: validationErrors
};
} // Execute
return execute({
schema,
document,
rootValue,
contextValue,
variableValues,
operationName,
fieldResolver,
typeResolver
});
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,19 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/internal/_xmap.js
import _curry2 from './_curry2.js';
import _xfBase from './_xfBase.js';
function XMap(f, xf) {
this.xf = xf;
this.f = f;
}
XMap.prototype['@@transducer/init'] = _xfBase.init;
XMap.prototype['@@transducer/result'] = _xfBase.result;
XMap.prototype['@@transducer/step'] = function(result, input) {
return this.xf['@@transducer/step'](result, this.f(input));
};
var _xmap = _curry2(function _xmap(f, xf) { return new XMap(f, xf); });
export default _xmap;

View File

@ -0,0 +1,45 @@
// Loaded from https://deno.land/std@0.77.0/io/writers.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
type Writer = Deno.Writer;
type WriterSync = Deno.WriterSync;
import { decode, encode } from "../encoding/utf8.ts";
/** Writer utility for buffering string chunks */
export class StringWriter implements Writer, WriterSync {
private chunks: Uint8Array[] = [];
private byteLength = 0;
private cache: string | undefined;
constructor(private base: string = "") {
const c = encode(base);
this.chunks.push(c);
this.byteLength += c.byteLength;
}
write(p: Uint8Array): Promise<number> {
return Promise.resolve(this.writeSync(p));
}
writeSync(p: Uint8Array): number {
this.chunks.push(p);
this.byteLength += p.byteLength;
this.cache = undefined;
return p.byteLength;
}
toString(): string {
if (this.cache) {
return this.cache;
}
const buf = new Uint8Array(this.byteLength);
let offs = 0;
for (const chunk of this.chunks) {
buf.set(chunk, offs);
offs += chunk.byteLength;
}
this.cache = decode(buf);
return this.cache;
}
}

View File

@ -0,0 +1,37 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/drop.js
import _curry2 from './internal/_curry2.js';
import _dispatchable from './internal/_dispatchable.js';
import _xdrop from './internal/_xdrop.js';
import slice from './slice.js';
/**
* Returns all but the first `n` elements of the given list, string, or
* transducer/transformer (or object with a `drop` method).
*
* Dispatches to the `drop` method of the second argument, if present.
*
* @func
* @memberOf R
* @since v0.1.0
* @category List
* @sig Number -> [a] -> [a]
* @sig Number -> String -> String
* @param {Number} n
* @param {*} list
* @return {*} A copy of list without the first `n` elements
* @see R.take, R.transduce, R.dropLast, R.dropWhile
* @example
*
* R.drop(1, ['foo', 'bar', 'baz']); //=> ['bar', 'baz']
* R.drop(2, ['foo', 'bar', 'baz']); //=> ['baz']
* R.drop(3, ['foo', 'bar', 'baz']); //=> []
* R.drop(4, ['foo', 'bar', 'baz']); //=> []
* R.drop(3, 'ramda'); //=> 'da'
*/
var drop = _curry2(_dispatchable(['drop'], _xdrop, function drop(n, xs) {
return slice(Math.max(0, n), Infinity, xs);
}));
export default drop;

View File

@ -0,0 +1,6 @@
// Loaded from https://deno.land/x/graphql_deno@v15.0.0/lib/jsutils/nodejsCustomInspectSymbol.js
/* istanbul ignore next (See: https://github.com/graphql/graphql-js/issues/2317) */
const nodejsCustomInspectSymbol = typeof Symbol === 'function' && typeof Symbol.for === 'function' ? Symbol.for('nodejs.util.inspect.custom') : undefined;
export default nodejsCustomInspectSymbol;

View File

@ -0,0 +1,33 @@
// Loaded from https://deno.land/std@0.73.0/path/_interface.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
/** This module is browser compatible. */
/**
* A parsed path object generated by path.parse() or consumed by path.format().
*/
export interface ParsedPath {
/**
* The root of the path such as '/' or 'c:\'
*/
root: string;
/**
* The full directory path such as '/home/user/dir' or 'c:\path\dir'
*/
dir: string;
/**
* The file name including extension (if any) such as 'index.html'
*/
base: string;
/**
* The file extension (if any) such as '.html'
*/
ext: string;
/**
* The file name without extension (if any) such as 'index'
*/
name: string;
}
export type FormatInputPathObject = Partial<ParsedPath>;

View File

@ -0,0 +1,10 @@
// Loaded from https://deno.land/std@0.79.0/path/separator.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
/** This module is browser compatible. */
import { isWindows } from "../_util/os.ts";
export const SEP = isWindows ? "\\" : "/";
export const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,29 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/internal/_xdropRepeatsWith.js
import _curry2 from './_curry2.js';
import _xfBase from './_xfBase.js';
function XDropRepeatsWith(pred, xf) {
this.xf = xf;
this.pred = pred;
this.lastValue = undefined;
this.seenFirstValue = false;
}
XDropRepeatsWith.prototype['@@transducer/init'] = _xfBase.init;
XDropRepeatsWith.prototype['@@transducer/result'] = _xfBase.result;
XDropRepeatsWith.prototype['@@transducer/step'] = function(result, input) {
var sameAsLast = false;
if (!this.seenFirstValue) {
this.seenFirstValue = true;
} else if (this.pred(this.lastValue, input)) {
sameAsLast = true;
}
this.lastValue = input;
return sameAsLast ? result : this.xf['@@transducer/step'](result, input);
};
var _xdropRepeatsWith = _curry2(function _xdropRepeatsWith(pred, xf) { return new XDropRepeatsWith(pred, xf); });
export default _xdropRepeatsWith;

View File

@ -0,0 +1,721 @@
// Loaded from https://deno.land/std@0.83.0/io/bufio.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
// Based on https://github.com/golang/go/blob/891682/src/bufio/bufio.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
type Reader = Deno.Reader;
type Writer = Deno.Writer;
type WriterSync = Deno.WriterSync;
import { copy } from "../bytes/mod.ts";
import { assert } from "../_util/assert.ts";
const DEFAULT_BUF_SIZE = 4096;
const MIN_BUF_SIZE = 16;
const MAX_CONSECUTIVE_EMPTY_READS = 100;
const CR = "\r".charCodeAt(0);
const LF = "\n".charCodeAt(0);
export class BufferFullError extends Error {
name = "BufferFullError";
constructor(public partial: Uint8Array) {
super("Buffer full");
}
}
export class PartialReadError extends Deno.errors.UnexpectedEof {
name = "PartialReadError";
partial?: Uint8Array;
constructor() {
super("Encountered UnexpectedEof, data only partially read");
}
}
/** Result type returned by of BufReader.readLine(). */
export interface ReadLineResult {
line: Uint8Array;
more: boolean;
}
/** BufReader implements buffering for a Reader object. */
export class BufReader implements Reader {
private buf!: Uint8Array;
private rd!: Reader; // Reader provided by caller.
private r = 0; // buf read position.
private w = 0; // buf write position.
private eof = false;
// private lastByte: number;
// private lastCharSize: number;
/** return new BufReader unless r is BufReader */
static create(r: Reader, size: number = DEFAULT_BUF_SIZE): BufReader {
return r instanceof BufReader ? r : new BufReader(r, size);
}
constructor(rd: Reader, size: number = DEFAULT_BUF_SIZE) {
if (size < MIN_BUF_SIZE) {
size = MIN_BUF_SIZE;
}
this._reset(new Uint8Array(size), rd);
}
/** Returns the size of the underlying buffer in bytes. */
size(): number {
return this.buf.byteLength;
}
buffered(): number {
return this.w - this.r;
}
// Reads a new chunk into the buffer.
private async _fill(): Promise<void> {
// Slide existing data to beginning.
if (this.r > 0) {
this.buf.copyWithin(0, this.r, this.w);
this.w -= this.r;
this.r = 0;
}
if (this.w >= this.buf.byteLength) {
throw Error("bufio: tried to fill full buffer");
}
// Read new data: try a limited number of times.
for (let i = MAX_CONSECUTIVE_EMPTY_READS; i > 0; i--) {
const rr = await this.rd.read(this.buf.subarray(this.w));
if (rr === null) {
this.eof = true;
return;
}
assert(rr >= 0, "negative read");
this.w += rr;
if (rr > 0) {
return;
}
}
throw new Error(
`No progress after ${MAX_CONSECUTIVE_EMPTY_READS} read() calls`,
);
}
/** Discards any buffered data, resets all state, and switches
* the buffered reader to read from r.
*/
reset(r: Reader): void {
this._reset(this.buf, r);
}
private _reset(buf: Uint8Array, rd: Reader): void {
this.buf = buf;
this.rd = rd;
this.eof = false;
// this.lastByte = -1;
// this.lastCharSize = -1;
}
/** reads data into p.
* It returns the number of bytes read into p.
* The bytes are taken from at most one Read on the underlying Reader,
* hence n may be less than len(p).
* To read exactly len(p) bytes, use io.ReadFull(b, p).
*/
async read(p: Uint8Array): Promise<number | null> {
let rr: number | null = p.byteLength;
if (p.byteLength === 0) return rr;
if (this.r === this.w) {
if (p.byteLength >= this.buf.byteLength) {
// Large read, empty buffer.
// Read directly into p to avoid copy.
const rr = await this.rd.read(p);
const nread = rr ?? 0;
assert(nread >= 0, "negative read");
// if (rr.nread > 0) {
// this.lastByte = p[rr.nread - 1];
// this.lastCharSize = -1;
// }
return rr;
}
// One read.
// Do not use this.fill, which will loop.
this.r = 0;
this.w = 0;
rr = await this.rd.read(this.buf);
if (rr === 0 || rr === null) return rr;
assert(rr >= 0, "negative read");
this.w += rr;
}
// copy as much as we can
const copied = copy(this.buf.subarray(this.r, this.w), p, 0);
this.r += copied;
// this.lastByte = this.buf[this.r - 1];
// this.lastCharSize = -1;
return copied;
}
/** reads exactly `p.length` bytes into `p`.
*
* If successful, `p` is returned.
*
* If the end of the underlying stream has been reached, and there are no more
* bytes available in the buffer, `readFull()` returns `null` instead.
*
* An error is thrown if some bytes could be read, but not enough to fill `p`
* entirely before the underlying stream reported an error or EOF. Any error
* thrown will have a `partial` property that indicates the slice of the
* buffer that has been successfully filled with data.
*
* Ported from https://golang.org/pkg/io/#ReadFull
*/
async readFull(p: Uint8Array): Promise<Uint8Array | null> {
let bytesRead = 0;
while (bytesRead < p.length) {
try {
const rr = await this.read(p.subarray(bytesRead));
if (rr === null) {
if (bytesRead === 0) {
return null;
} else {
throw new PartialReadError();
}
}
bytesRead += rr;
} catch (err) {
err.partial = p.subarray(0, bytesRead);
throw err;
}
}
return p;
}
/** Returns the next byte [0, 255] or `null`. */
async readByte(): Promise<number | null> {
while (this.r === this.w) {
if (this.eof) return null;
await this._fill(); // buffer is empty.
}
const c = this.buf[this.r];
this.r++;
// this.lastByte = c;
return c;
}
/** readString() reads until the first occurrence of delim in the input,
* returning a string containing the data up to and including the delimiter.
* If ReadString encounters an error before finding a delimiter,
* it returns the data read before the error and the error itself
* (often `null`).
* ReadString returns err != nil if and only if the returned data does not end
* in delim.
* For simple uses, a Scanner may be more convenient.
*/
async readString(delim: string): Promise<string | null> {
if (delim.length !== 1) {
throw new Error("Delimiter should be a single character");
}
const buffer = await this.readSlice(delim.charCodeAt(0));
if (buffer === null) return null;
return new TextDecoder().decode(buffer);
}
/** `readLine()` is a low-level line-reading primitive. Most callers should
* use `readString('\n')` instead or use a Scanner.
*
* `readLine()` tries to return a single line, not including the end-of-line
* bytes. If the line was too long for the buffer then `more` is set and the
* beginning of the line is returned. The rest of the line will be returned
* from future calls. `more` will be false when returning the last fragment
* of the line. The returned buffer is only valid until the next call to
* `readLine()`.
*
* The text returned from ReadLine does not include the line end ("\r\n" or
* "\n").
*
* When the end of the underlying stream is reached, the final bytes in the
* stream are returned. No indication or error is given if the input ends
* without a final line end. When there are no more trailing bytes to read,
* `readLine()` returns `null`.
*
* Calling `unreadByte()` after `readLine()` will always unread the last byte
* read (possibly a character belonging to the line end) even if that byte is
* not part of the line returned by `readLine()`.
*/
async readLine(): Promise<ReadLineResult | null> {
let line: Uint8Array | null;
try {
line = await this.readSlice(LF);
} catch (err) {
let { partial } = err;
assert(
partial instanceof Uint8Array,
"bufio: caught error from `readSlice()` without `partial` property",
);
// Don't throw if `readSlice()` failed with `BufferFullError`, instead we
// just return whatever is available and set the `more` flag.
if (!(err instanceof BufferFullError)) {
throw err;
}
// Handle the case where "\r\n" straddles the buffer.
if (
!this.eof &&
partial.byteLength > 0 &&
partial[partial.byteLength - 1] === CR
) {
// Put the '\r' back on buf and drop it from line.
// Let the next call to ReadLine check for "\r\n".
assert(this.r > 0, "bufio: tried to rewind past start of buffer");
this.r--;
partial = partial.subarray(0, partial.byteLength - 1);
}
return { line: partial, more: !this.eof };
}
if (line === null) {
return null;
}
if (line.byteLength === 0) {
return { line, more: false };
}
if (line[line.byteLength - 1] == LF) {
let drop = 1;
if (line.byteLength > 1 && line[line.byteLength - 2] === CR) {
drop = 2;
}
line = line.subarray(0, line.byteLength - drop);
}
return { line, more: false };
}
/** `readSlice()` reads until the first occurrence of `delim` in the input,
* returning a slice pointing at the bytes in the buffer. The bytes stop
* being valid at the next read.
*
* If `readSlice()` encounters an error before finding a delimiter, or the
* buffer fills without finding a delimiter, it throws an error with a
* `partial` property that contains the entire buffer.
*
* If `readSlice()` encounters the end of the underlying stream and there are
* any bytes left in the buffer, the rest of the buffer is returned. In other
* words, EOF is always treated as a delimiter. Once the buffer is empty,
* it returns `null`.
*
* Because the data returned from `readSlice()` will be overwritten by the
* next I/O operation, most clients should use `readString()` instead.
*/
async readSlice(delim: number): Promise<Uint8Array | null> {
let s = 0; // search start index
let slice: Uint8Array | undefined;
while (true) {
// Search buffer.
let i = this.buf.subarray(this.r + s, this.w).indexOf(delim);
if (i >= 0) {
i += s;
slice = this.buf.subarray(this.r, this.r + i + 1);
this.r += i + 1;
break;
}
// EOF?
if (this.eof) {
if (this.r === this.w) {
return null;
}
slice = this.buf.subarray(this.r, this.w);
this.r = this.w;
break;
}
// Buffer full?
if (this.buffered() >= this.buf.byteLength) {
this.r = this.w;
// #4521 The internal buffer should not be reused across reads because it causes corruption of data.
const oldbuf = this.buf;
const newbuf = this.buf.slice(0);
this.buf = newbuf;
throw new BufferFullError(oldbuf);
}
s = this.w - this.r; // do not rescan area we scanned before
// Buffer is not full.
try {
await this._fill();
} catch (err) {
err.partial = slice;
throw err;
}
}
// Handle last byte, if any.
// const i = slice.byteLength - 1;
// if (i >= 0) {
// this.lastByte = slice[i];
// this.lastCharSize = -1
// }
return slice;
}
/** `peek()` returns the next `n` bytes without advancing the reader. The
* bytes stop being valid at the next read call.
*
* When the end of the underlying stream is reached, but there are unread
* bytes left in the buffer, those bytes are returned. If there are no bytes
* left in the buffer, it returns `null`.
*
* If an error is encountered before `n` bytes are available, `peek()` throws
* an error with the `partial` property set to a slice of the buffer that
* contains the bytes that were available before the error occurred.
*/
async peek(n: number): Promise<Uint8Array | null> {
if (n < 0) {
throw Error("negative count");
}
let avail = this.w - this.r;
while (avail < n && avail < this.buf.byteLength && !this.eof) {
try {
await this._fill();
} catch (err) {
err.partial = this.buf.subarray(this.r, this.w);
throw err;
}
avail = this.w - this.r;
}
if (avail === 0 && this.eof) {
return null;
} else if (avail < n && this.eof) {
return this.buf.subarray(this.r, this.r + avail);
} else if (avail < n) {
throw new BufferFullError(this.buf.subarray(this.r, this.w));
}
return this.buf.subarray(this.r, this.r + n);
}
}
abstract class AbstractBufBase {
buf!: Uint8Array;
usedBufferBytes = 0;
err: Error | null = null;
/** Size returns the size of the underlying buffer in bytes. */
size(): number {
return this.buf.byteLength;
}
/** Returns how many bytes are unused in the buffer. */
available(): number {
return this.buf.byteLength - this.usedBufferBytes;
}
/** buffered returns the number of bytes that have been written into the
* current buffer.
*/
buffered(): number {
return this.usedBufferBytes;
}
}
/** BufWriter implements buffering for an deno.Writer object.
* If an error occurs writing to a Writer, no more data will be
* accepted and all subsequent writes, and flush(), will return the error.
* After all data has been written, the client should call the
* flush() method to guarantee all data has been forwarded to
* the underlying deno.Writer.
*/
export class BufWriter extends AbstractBufBase implements Writer {
/** return new BufWriter unless writer is BufWriter */
static create(writer: Writer, size: number = DEFAULT_BUF_SIZE): BufWriter {
return writer instanceof BufWriter ? writer : new BufWriter(writer, size);
}
constructor(private writer: Writer, size: number = DEFAULT_BUF_SIZE) {
super();
if (size <= 0) {
size = DEFAULT_BUF_SIZE;
}
this.buf = new Uint8Array(size);
}
/** Discards any unflushed buffered data, clears any error, and
* resets buffer to write its output to w.
*/
reset(w: Writer): void {
this.err = null;
this.usedBufferBytes = 0;
this.writer = w;
}
/** Flush writes any buffered data to the underlying io.Writer. */
async flush(): Promise<void> {
if (this.err !== null) throw this.err;
if (this.usedBufferBytes === 0) return;
try {
await Deno.writeAll(
this.writer,
this.buf.subarray(0, this.usedBufferBytes),
);
} catch (e) {
this.err = e;
throw e;
}
this.buf = new Uint8Array(this.buf.length);
this.usedBufferBytes = 0;
}
/** Writes the contents of `data` into the buffer. If the contents won't fully
* fit into the buffer, those bytes that can are copied into the buffer, the
* buffer is the flushed to the writer and the remaining bytes are copied into
* the now empty buffer.
*
* @return the number of bytes written to the buffer.
*/
async write(data: Uint8Array): Promise<number> {
if (this.err !== null) throw this.err;
if (data.length === 0) return 0;
let totalBytesWritten = 0;
let numBytesWritten = 0;
while (data.byteLength > this.available()) {
if (this.buffered() === 0) {
// Large write, empty buffer.
// Write directly from data to avoid copy.
try {
numBytesWritten = await this.writer.write(data);
} catch (e) {
this.err = e;
throw e;
}
} else {
numBytesWritten = copy(data, this.buf, this.usedBufferBytes);
this.usedBufferBytes += numBytesWritten;
await this.flush();
}
totalBytesWritten += numBytesWritten;
data = data.subarray(numBytesWritten);
}
numBytesWritten = copy(data, this.buf, this.usedBufferBytes);
this.usedBufferBytes += numBytesWritten;
totalBytesWritten += numBytesWritten;
return totalBytesWritten;
}
}
/** BufWriterSync implements buffering for a deno.WriterSync object.
* If an error occurs writing to a WriterSync, no more data will be
* accepted and all subsequent writes, and flush(), will return the error.
* After all data has been written, the client should call the
* flush() method to guarantee all data has been forwarded to
* the underlying deno.WriterSync.
*/
export class BufWriterSync extends AbstractBufBase implements WriterSync {
/** return new BufWriterSync unless writer is BufWriterSync */
static create(
writer: WriterSync,
size: number = DEFAULT_BUF_SIZE,
): BufWriterSync {
return writer instanceof BufWriterSync
? writer
: new BufWriterSync(writer, size);
}
constructor(private writer: WriterSync, size: number = DEFAULT_BUF_SIZE) {
super();
if (size <= 0) {
size = DEFAULT_BUF_SIZE;
}
this.buf = new Uint8Array(size);
}
/** Discards any unflushed buffered data, clears any error, and
* resets buffer to write its output to w.
*/
reset(w: WriterSync): void {
this.err = null;
this.usedBufferBytes = 0;
this.writer = w;
}
/** Flush writes any buffered data to the underlying io.WriterSync. */
flush(): void {
if (this.err !== null) throw this.err;
if (this.usedBufferBytes === 0) return;
try {
Deno.writeAllSync(
this.writer,
this.buf.subarray(0, this.usedBufferBytes),
);
} catch (e) {
this.err = e;
throw e;
}
this.buf = new Uint8Array(this.buf.length);
this.usedBufferBytes = 0;
}
/** Writes the contents of `data` into the buffer. If the contents won't fully
* fit into the buffer, those bytes that can are copied into the buffer, the
* buffer is the flushed to the writer and the remaining bytes are copied into
* the now empty buffer.
*
* @return the number of bytes written to the buffer.
*/
writeSync(data: Uint8Array): number {
if (this.err !== null) throw this.err;
if (data.length === 0) return 0;
let totalBytesWritten = 0;
let numBytesWritten = 0;
while (data.byteLength > this.available()) {
if (this.buffered() === 0) {
// Large write, empty buffer.
// Write directly from data to avoid copy.
try {
numBytesWritten = this.writer.writeSync(data);
} catch (e) {
this.err = e;
throw e;
}
} else {
numBytesWritten = copy(data, this.buf, this.usedBufferBytes);
this.usedBufferBytes += numBytesWritten;
this.flush();
}
totalBytesWritten += numBytesWritten;
data = data.subarray(numBytesWritten);
}
numBytesWritten = copy(data, this.buf, this.usedBufferBytes);
this.usedBufferBytes += numBytesWritten;
totalBytesWritten += numBytesWritten;
return totalBytesWritten;
}
}
/** Generate longest proper prefix which is also suffix array. */
function createLPS(pat: Uint8Array): Uint8Array {
const lps = new Uint8Array(pat.length);
lps[0] = 0;
let prefixEnd = 0;
let i = 1;
while (i < lps.length) {
if (pat[i] == pat[prefixEnd]) {
prefixEnd++;
lps[i] = prefixEnd;
i++;
} else if (prefixEnd === 0) {
lps[i] = 0;
i++;
} else {
prefixEnd = pat[prefixEnd - 1];
}
}
return lps;
}
/** Read delimited bytes from a Reader. */
export async function* readDelim(
reader: Reader,
delim: Uint8Array,
): AsyncIterableIterator<Uint8Array> {
// Avoid unicode problems
const delimLen = delim.length;
const delimLPS = createLPS(delim);
let inputBuffer = new Deno.Buffer();
const inspectArr = new Uint8Array(Math.max(1024, delimLen + 1));
// Modified KMP
let inspectIndex = 0;
let matchIndex = 0;
while (true) {
const result = await reader.read(inspectArr);
if (result === null) {
// Yield last chunk.
yield inputBuffer.bytes();
return;
}
if ((result as number) < 0) {
// Discard all remaining and silently fail.
return;
}
const sliceRead = inspectArr.subarray(0, result as number);
await Deno.writeAll(inputBuffer, sliceRead);
let sliceToProcess = inputBuffer.bytes();
while (inspectIndex < sliceToProcess.length) {
if (sliceToProcess[inspectIndex] === delim[matchIndex]) {
inspectIndex++;
matchIndex++;
if (matchIndex === delimLen) {
// Full match
const matchEnd = inspectIndex - delimLen;
const readyBytes = sliceToProcess.subarray(0, matchEnd);
// Copy
const pendingBytes = sliceToProcess.slice(inspectIndex);
yield readyBytes;
// Reset match, different from KMP.
sliceToProcess = pendingBytes;
inspectIndex = 0;
matchIndex = 0;
}
} else {
if (matchIndex === 0) {
inspectIndex++;
} else {
matchIndex = delimLPS[matchIndex - 1];
}
}
}
// Keep inspectIndex and matchIndex.
inputBuffer = new Deno.Buffer(sliceToProcess);
}
}
/** Read delimited strings from a Reader. */
export async function* readStringDelim(
reader: Reader,
delim: string,
): AsyncIterableIterator<string> {
const encoder = new TextEncoder();
const decoder = new TextDecoder();
for await (const chunk of readDelim(reader, encoder.encode(delim))) {
yield decoder.decode(chunk);
}
}
/** Read strings line-by-line from a Reader. */
export async function* readLines(
reader: Reader,
): AsyncIterableIterator<string> {
for await (let chunk of readStringDelim(reader, "\n")) {
// Finding a CR at the end of the line is evidence of a
// "\r\n" at the end of the line. The "\r" part should be
// removed too.
if (chunk.endsWith("\r")) {
chunk = chunk.slice(0, -1);
}
yield chunk;
}
}

View File

@ -0,0 +1,66 @@
// Loaded from https://deno.land/x/mysql/src/packets/builders/auth.ts
import auth from "../../auth.ts";
import { BufferWriter } from "../../buffer.ts";
import ServerCapabilities from "../../constant/capabilities.ts";
import { Charset } from "../../constant/charset.ts";
import type { HandshakeBody } from "../parsers/handshake.ts";
/** @ignore */
export function buildAuth(
packet: HandshakeBody,
params: { username: string; password?: string; db?: string },
): Uint8Array {
const clientParam: number =
(params.db ? ServerCapabilities.CLIENT_CONNECT_WITH_DB : 0) |
ServerCapabilities.CLIENT_PLUGIN_AUTH |
ServerCapabilities.CLIENT_LONG_PASSWORD |
ServerCapabilities.CLIENT_PROTOCOL_41 |
ServerCapabilities.CLIENT_TRANSACTIONS |
ServerCapabilities.CLIENT_MULTI_RESULTS |
ServerCapabilities.CLIENT_SECURE_CONNECTION |
(ServerCapabilities.CLIENT_LONG_FLAG & packet.serverCapabilities) |
(ServerCapabilities.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA &
packet.serverCapabilities) |
(ServerCapabilities.CLIENT_DEPRECATE_EOF & packet.serverCapabilities);
if (packet.serverCapabilities & ServerCapabilities.CLIENT_PLUGIN_AUTH) {
const writer = new BufferWriter(new Uint8Array(1000));
writer
.writeUint32(clientParam)
.writeUint32(2 ** 24 - 1)
.write(Charset.UTF8_GENERAL_CI)
.skip(23)
.writeNullTerminatedString(params.username);
if (params.password) {
const authData = auth(
packet.authPluginName,
params.password,
packet.seed,
);
if (
clientParam &
ServerCapabilities.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA ||
clientParam & ServerCapabilities.CLIENT_SECURE_CONNECTION
) {
// request lenenc-int length of auth-response and string[n] auth-response
writer.write(authData.length);
writer.writeBuffer(authData);
} else {
writer.writeBuffer(authData);
writer.write(0);
}
} else {
writer.write(0);
}
if (clientParam & ServerCapabilities.CLIENT_CONNECT_WITH_DB && params.db) {
writer.writeNullTerminatedString(params.db);
}
if (clientParam & ServerCapabilities.CLIENT_PLUGIN_AUTH) {
writer.writeNullTerminatedString(packet.authPluginName);
}
return writer.wroteData;
}
return Uint8Array.from([]);
}

View File

@ -0,0 +1,53 @@
// Loaded from https://deno.land/x/segno@v1.1.0/lib/validations/isDate.ts
/**
* @ignore
*/
const isValidFormat = (format: string) => {
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(
format
);
};
/**
* @ignore
*/
const zip = (date: string[], format: string[]) => {
const zippedArr = [];
const len = Math.min(date.length, format.length);
for (let i = 0; i < len; i++) {
zippedArr.push([date[i], format[i]]);
}
return zippedArr;
};
export const isDate = (input: any, format = 'YYYY/MM/DD') => {
if (typeof input === 'string' && isValidFormat(format)) {
const splitter = /[-/]/;
const dateAndFormat = zip(
input.split(splitter),
format.toLowerCase().split(splitter)
);
const dateObj = {} as any;
for (const [dateWord, formatWord] of dateAndFormat) {
if (dateWord.length !== formatWord.length) {
return false;
}
dateObj[formatWord.charAt(0)] = dateWord;
}
return (
new Date(`${dateObj.m}/${dateObj.d}/${dateObj.y}`).getDate() ===
+dateObj.d
);
}
return (
Object.prototype.toString.call(input) === '[object Date]' && isFinite(input)
);
};

View File

@ -0,0 +1,123 @@
// Loaded from https://deno.land/x/segno@v1.1.0/lib/validations/isCurrency.ts
// @ts-ignore allowing typedoc to build
import { assertString } from '../helpers/assertString.ts';
type CurrencyOptions = {
symbol?: string;
requireSymbol?: boolean;
allowSpaceAfterSymbol?: boolean;
symbolAfterDigits?: boolean;
allowNegatives?: boolean;
parensForNegatives?: boolean;
negativeSignBeforeDigits?: boolean;
negativeSignAfterDigits?: boolean;
allowNegativeSignPlaceholder?: boolean;
thousandsSeparator?: string;
decimalSeparator?: string;
allowDecimal?: boolean;
requireDecimal?: boolean;
digitsAfterDecimal?: number[];
allowSpaceAfterDigits?: boolean;
};
/**
* @ignore
*/
const currencyRegex = (options: Required<CurrencyOptions>) => {
let decimalDigits = `\\d{${options.digitsAfterDecimal[0]}}`;
options.digitsAfterDecimal.forEach((digit, index) => {
if (index !== 0) decimalDigits = `${decimalDigits}|\\d{${digit}}`;
});
const symbol = `(${options.symbol.replace(/\W/, (m) => `\\${m}`)})${
options.requireSymbol ? '' : '?'
}`,
negative = '-?',
whole_dollar_amount_without_sep = '[1-9]\\d*',
whole_dollar_amount_with_sep = `[1-9]\\d{0,2}(\\${options.thousandsSeparator}\\d{3})*`,
valid_whole_dollar_amounts = [
'0',
whole_dollar_amount_without_sep,
whole_dollar_amount_with_sep,
],
whole_dollar_amount = `(${valid_whole_dollar_amounts.join('|')})?`,
decimal_amount = `(\\${options.decimalSeparator}(${decimalDigits}))${
options.requireDecimal ? '' : '?'
}`;
let pattern =
whole_dollar_amount +
(options.allowDecimal || options.requireDecimal ? decimal_amount : '');
// default is negative sign before symbol, but there are two other options (besides parens)
if (options.allowNegatives && !options.parensForNegatives) {
if (options.negativeSignAfterDigits) {
pattern += negative;
} else if (options.negativeSignBeforeDigits) {
pattern = negative + pattern;
}
}
// South African Rand, for example, uses R 123 (space) and R-123 (no space)
if (options.allowNegativeSignPlaceholder) {
pattern = `( (?!\\-))?${pattern}`;
} else if (options.allowSpaceAfterSymbol) {
pattern = ` ?${pattern}`;
} else if (options.allowSpaceAfterDigits) {
pattern += '( (?!$))?';
}
if (options.symbolAfterDigits) {
pattern += symbol;
} else {
pattern = symbol + pattern;
}
if (options.allowNegatives) {
if (options.parensForNegatives) {
pattern = `(\\(${pattern}\\)|${pattern})`;
} else if (
!(options.negativeSignBeforeDigits || options.negativeSignAfterDigits)
) {
pattern = negative + pattern;
}
}
// ensure there's a dollar and/or decimal amount, and that
// it doesn't start with a space or a negative sign followed by a space
return new RegExp(`^(?!-? )(?=.*\\d)${pattern}$`);
};
/**
* @ignore
*/
const defaultCurrencyOptions: CurrencyOptions = {
symbol: '$',
requireSymbol: false,
allowSpaceAfterSymbol: false,
symbolAfterDigits: false,
allowNegatives: true,
parensForNegatives: false,
negativeSignBeforeDigits: false,
negativeSignAfterDigits: false,
allowNegativeSignPlaceholder: false,
thousandsSeparator: ',',
decimalSeparator: '.',
allowDecimal: true,
requireDecimal: false,
digitsAfterDecimal: [2],
allowSpaceAfterDigits: false,
};
export const isCurrency = (str: string, options?: CurrencyOptions) => {
assertString(str);
options = {
...defaultCurrencyOptions,
...options,
};
return currencyRegex(options as Required<CurrencyOptions>).test(str);
};

View File

@ -0,0 +1,207 @@
// Loaded from https://deno.land/std@0.81.0/http/cookie.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
// Structured similarly to Go's cookie.go
// https://github.com/golang/go/blob/master/src/net/http/cookie.go
import { assert } from "../_util/assert.ts";
import { toIMF } from "../datetime/mod.ts";
export type Cookies = Record<string, string>;
export interface Cookie {
/** Name of the cookie. */
name: string;
/** Value of the cookie. */
value: string;
/** Expiration date of the cookie. */
expires?: Date;
/** Max-Age of the Cookie. Must be integer superior to 0. */
maxAge?: number;
/** Specifies those hosts to which the cookie will be sent. */
domain?: string;
/** Indicates a URL path that must exist in the request. */
path?: string;
/** Indicates if the cookie is made using SSL & HTTPS. */
secure?: boolean;
/** Indicates that cookie is not accessible via JavaScript. **/
httpOnly?: boolean;
/** Allows servers to assert that a cookie ought not to
* be sent along with cross-site requests. */
sameSite?: SameSite;
/** Additional key value pairs with the form "key=value" */
unparsed?: string[];
}
export type SameSite = "Strict" | "Lax" | "None";
const FIELD_CONTENT_REGEXP = /^(?=[\x20-\x7E]*$)[^()@<>,;:\\"\[\]?={}\s]+$/;
function toString(cookie: Cookie): string {
if (!cookie.name) {
return "";
}
const out: string[] = [];
validateCookieName(cookie.name);
validateCookieValue(cookie.name, cookie.value);
out.push(`${cookie.name}=${cookie.value}`);
// Fallback for invalid Set-Cookie
// ref: https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1
if (cookie.name.startsWith("__Secure")) {
cookie.secure = true;
}
if (cookie.name.startsWith("__Host")) {
cookie.path = "/";
cookie.secure = true;
delete cookie.domain;
}
if (cookie.secure) {
out.push("Secure");
}
if (cookie.httpOnly) {
out.push("HttpOnly");
}
if (typeof cookie.maxAge === "number" && Number.isInteger(cookie.maxAge)) {
assert(cookie.maxAge > 0, "Max-Age must be an integer superior to 0");
out.push(`Max-Age=${cookie.maxAge}`);
}
if (cookie.domain) {
out.push(`Domain=${cookie.domain}`);
}
if (cookie.sameSite) {
out.push(`SameSite=${cookie.sameSite}`);
}
if (cookie.path) {
validatePath(cookie.path);
out.push(`Path=${cookie.path}`);
}
if (cookie.expires) {
const dateString = toIMF(cookie.expires);
out.push(`Expires=${dateString}`);
}
if (cookie.unparsed) {
out.push(cookie.unparsed.join("; "));
}
return out.join("; ");
}
/**
* Validate Cookie Name.
* @param name Cookie name.
*/
function validateCookieName(name: string | undefined | null): void {
if (name && !FIELD_CONTENT_REGEXP.test(name)) {
throw new TypeError(`Invalid cookie name: "${name}".`);
}
}
/**
* Validate Path Value.
* @see https://tools.ietf.org/html/rfc6265#section-4.1.2.4
* @param path Path value.
*/
function validatePath(path: string | null): void {
if (path == null) {
return;
}
for (let i = 0; i < path.length; i++) {
const c = path.charAt(i);
if (
c < String.fromCharCode(0x20) || c > String.fromCharCode(0x7E) || c == ";"
) {
throw new Error(
path + ": Invalid cookie path char '" + c + "'",
);
}
}
}
/**
*Validate Cookie Value.
* @see https://tools.ietf.org/html/rfc6265#section-4.1
* @param value Cookie value.
*/
function validateCookieValue(name: string, value: string | null): void {
if (value == null || name == null) return;
for (let i = 0; i < value.length; i++) {
const c = value.charAt(i);
if (
c < String.fromCharCode(0x21) || c == String.fromCharCode(0x22) ||
c == String.fromCharCode(0x2c) || c == String.fromCharCode(0x3b) ||
c == String.fromCharCode(0x5c) || c == String.fromCharCode(0x7f)
) {
throw new Error(
"RFC2616 cookie '" + name + "' cannot have '" + c + "' as value",
);
}
if (c > String.fromCharCode(0x80)) {
throw new Error(
"RFC2616 cookie '" + name + "' can only have US-ASCII chars as value" +
c.charCodeAt(0).toString(16),
);
}
}
}
/**
* Parse the cookies of the Server Request
* @param req An object which has a `headers` property
*/
export function getCookies(req: { headers: Headers }): Cookies {
const cookie = req.headers.get("Cookie");
if (cookie != null) {
const out: Cookies = {};
const c = cookie.split(";");
for (const kv of c) {
const [cookieKey, ...cookieVal] = kv.split("=");
assert(cookieKey != null);
const key = cookieKey.trim();
out[key] = cookieVal.join("=");
}
return out;
}
return {};
}
/**
* Set the cookie header properly in the Response
* @param res An object which has a headers property
* @param cookie Cookie to set
*
* Example:
*
* ```ts
* setCookie(response, { name: 'deno', value: 'runtime',
* httpOnly: true, secure: true, maxAge: 2, domain: "deno.land" });
* ```
*/
export function setCookie(res: { headers?: Headers }, cookie: Cookie): void {
if (!res.headers) {
res.headers = new Headers();
}
// TODO (zekth) : Add proper parsing of Set-Cookie headers
// Parsing cookie headers to make consistent set-cookie header
// ref: https://tools.ietf.org/html/rfc6265#section-4.1.1
const v = toString(cookie);
if (v) {
res.headers.append("Set-Cookie", v);
}
}
/**
* Set the cookie header properly in the Response to delete it
* @param res Server Response
* @param name Name of the cookie to Delete
* Example:
*
* deleteCookie(res,'foo');
*/
export function deleteCookie(res: { headers?: Headers }, name: string): void {
setCookie(res, {
name: name,
value: "",
expires: new Date(0),
});
}

View File

@ -0,0 +1,9 @@
// Loaded from https://deno.land/std@0.77.0/io/mod.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
export * from "./bufio.ts";
export * from "./ioutil.ts";
export * from "./readers.ts";
export * from "./writers.ts";
export * from "./streams.ts";

View File

@ -0,0 +1,44 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/internal/_clone.js
import _cloneRegExp from './_cloneRegExp.js';
import type from '../type.js';
/**
* Copies an object.
*
* @private
* @param {*} value The value to be copied
* @param {Array} refFrom Array containing the source references
* @param {Array} refTo Array containing the copied source references
* @param {Boolean} deep Whether or not to perform deep cloning.
* @return {*} The copied value.
*/
export default function _clone(value, refFrom, refTo, deep) {
var copy = function copy(copiedValue) {
var len = refFrom.length;
var idx = 0;
while (idx < len) {
if (value === refFrom[idx]) {
return refTo[idx];
}
idx += 1;
}
refFrom[idx] = value;
refTo[idx] = copiedValue;
for (var key in value) {
if (value.hasOwnProperty(key)) {
copiedValue[key] = deep ? _clone(value[key], refFrom, refTo, true) : value[key];
}
}
return copiedValue;
};
switch (type(value)) {
case 'Object': return copy(Object.create(Object.getPrototypeOf(value)));
case 'Array': return copy([]);
case 'Date': return new Date(value.valueOf());
case 'RegExp': return _cloneRegExp(value);
default: return value;
}
}

View File

@ -0,0 +1,36 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/pick.js
import _curry2 from './internal/_curry2.js';
/**
* Returns a partial copy of an object containing only the keys specified. If
* the key does not exist, the property is ignored.
*
* @func
* @memberOf R
* @since v0.1.0
* @category Object
* @sig [k] -> {k: v} -> {k: v}
* @param {Array} names an array of String property names to copy onto a new object
* @param {Object} obj The object to copy from
* @return {Object} A new object with only properties from `names` on it.
* @see R.omit, R.props
* @example
*
* R.pick(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, d: 4}
* R.pick(['a', 'e', 'f'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1}
*/
var pick = _curry2(function pick(names, obj) {
var result = {};
var idx = 0;
while (idx < names.length) {
if (names[idx] in obj) {
result[names[idx]] = obj[names[idx]];
}
idx += 1;
}
return result;
});
export default pick;

View File

@ -0,0 +1,84 @@
// Loaded from https://deno.land/x/denodb@v1.0.18/lib/relationships.ts
import type { ModelSchema } from "./model.ts";
import { DataTypes, FieldTypeString, RelationshipType } from "./data-types.ts";
import { PivotModel } from "./model-pivot.ts";
type RelationshipOptions = {
primaryKey?: string;
foreignKey?: string;
};
export const Relationships = {
/** Define a one-to-one or one-to-many relationship for a given model. */
belongsTo(model: ModelSchema): RelationshipType {
return {
type: DataTypes.INTEGER,
relationship: {
kind: "single",
model,
},
};
},
/** Add corresponding fields to each model for a one-to-one relationship. */
oneToOne(
modelA: ModelSchema,
modelB: ModelSchema,
options?: RelationshipOptions,
) {
let primaryKey = options?.primaryKey;
let foreignKey = options?.foreignKey;
modelA.fields[primaryKey || `${modelB.name.toLowerCase()}Id`] = this
.belongsTo(modelB);
modelB.fields[foreignKey || `${modelA.name.toLowerCase()}Id`] = this
.belongsTo(modelA);
},
/** Generate a many-to-many pivot model for two given models.
*
* const AirportFlight = Relationships.manyToMany(Airport, Flight);
*/
manyToMany(
modelA: ModelSchema,
modelB: ModelSchema,
options?: RelationshipOptions,
): ModelSchema {
let primaryKey = options?.primaryKey;
let foreignKey = options?.foreignKey;
const pivotClassName = `${modelA.table}_${modelB.table}`;
const modelAFieldName = primaryKey || `${modelA.name.toLowerCase()}Id`;
const modelBFieldName = foreignKey || `${modelB.name.toLowerCase()}Id`;
class PivotClass extends PivotModel {
static table = pivotClassName;
static fields = {
id: {
primaryKey: true,
autoIncrement: true,
},
[modelAFieldName]: Relationships.belongsTo(modelA),
[modelBFieldName]: Relationships.belongsTo(modelB),
};
static _pivotsModels = {
[modelA.name]: modelA,
[modelB.name]: modelB,
};
static _pivotsFields = {
[modelA.name]: modelAFieldName,
[modelB.name]: modelBFieldName,
};
}
modelA.pivot[modelB.name] = PivotClass;
modelB.pivot[modelA.name] = PivotClass;
return PivotClass;
},
};

View File

@ -0,0 +1,34 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/zipObj.js
import _curry2 from './internal/_curry2.js';
/**
* Creates a new object out of a list of keys and a list of values.
* Key/value pairing is truncated to the length of the shorter of the two lists.
* Note: `zipObj` is equivalent to `pipe(zip, fromPairs)`.
*
* @func
* @memberOf R
* @since v0.3.0
* @category List
* @sig [String] -> [*] -> {String: *}
* @param {Array} keys The array that will be properties on the output object.
* @param {Array} values The list of values on the output object.
* @return {Object} The object made by pairing up same-indexed elements of `keys` and `values`.
* @example
*
* R.zipObj(['a', 'b', 'c'], [1, 2, 3]); //=> {a: 1, b: 2, c: 3}
*/
var zipObj = _curry2(function zipObj(keys, values) {
var idx = 0;
var len = Math.min(keys.length, values.length);
var out = {};
while (idx < len) {
out[keys[idx]] = values[idx];
idx += 1;
}
return out;
});
export default zipObj;

View File

@ -0,0 +1,185 @@
// Loaded from https://deno.land/x/oak@v6.3.1/context.ts
// Copyright 2018-2020 the oak authors. All rights reserved. MIT license.
import type { Application, State } from "./application.ts";
import { Cookies } from "./cookies.ts";
import { acceptable, acceptWebSocket, WebSocket } from "./deps.ts";
import { createHttpError } from "./httpError.ts";
import type { KeyStack } from "./keyStack.ts";
import { Request } from "./request.ts";
import { Response } from "./response.ts";
import { send, SendOptions } from "./send.ts";
import {
ServerSentEventTarget,
ServerSentEventTargetOptions,
} from "./server_sent_event.ts";
import type { ErrorStatus, ServerRequest } from "./types.d.ts";
export interface ContextSendOptions extends SendOptions {
/** The filename to send, which will be resolved based on the other options.
* If this property is omitted, the current context's `.request.url.pathname`
* will be used. */
path?: string;
}
/** Provides context about the current request and response to middleware
* functions. */
// deno-lint-ignore no-explicit-any
export class Context<S extends State = Record<string, any>> {
#socket?: WebSocket;
#sse?: ServerSentEventTarget;
/** A reference to the current application. */
app: Application<State>;
/** An object which allows access to cookies, mediating both the request and
* response. */
cookies: Cookies;
/** Is `true` if the current connection is upgradeable to a web socket.
* Otherwise the value is `false`. Use `.upgrade()` to upgrade the connection
* and return the web socket. */
get isUpgradable(): boolean {
return acceptable(this.request);
}
/** Determines if the request should be responded to. If `false` when the
* middleware completes processing, the response will not be sent back to the
* requestor. Typically this is used if the middleware will take over low
* level processing of requests and responses, for example if using web
* sockets. This automatically gets set to `false` when the context is
* upgraded to a web socket via the `.upgrade()` method.
*
* The default is `true`. */
respond: boolean;
/** An object which contains information about the current request. */
request: Request;
/** An object which contains information about the response that will be sent
* when the middleware finishes processing. */
response: Response;
/** If the the current context has been upgraded, then this will be set to
* with the web socket, otherwise it is `undefined`. */
get socket(): WebSocket | undefined {
return this.#socket;
}
/** The object to pass state to front-end views. This can be typed by
* supplying the generic state argument when creating a new app. For
* example:
*
* ```ts
* const app = new Application<{ foo: string }>();
* ```
*
* Or can be contextually inferred based on setting an initial state object:
*
* ```ts
* const app = new Application({ state: { foo: "bar" } });
* ```
*/
state: S;
constructor(
app: Application<S>,
serverRequest: ServerRequest,
secure = false,
) {
this.app = app;
this.state = app.state;
this.request = new Request(serverRequest, app.proxy, secure);
this.respond = true;
this.response = new Response(this.request);
this.cookies = new Cookies(this.request, this.response, {
keys: this.app.keys as KeyStack | undefined,
secure: this.request.secure,
});
}
/** Asserts the condition and if the condition fails, creates an HTTP error
* with the provided status (which defaults to `500`). The error status by
* default will be set on the `.response.status`.
*/
assert(
// deno-lint-ignore no-explicit-any
condition: any,
errorStatus: ErrorStatus = 500,
message?: string,
props?: Record<string, unknown>,
): asserts condition {
if (condition) {
return;
}
const err = createHttpError(errorStatus, message);
if (props) {
Object.assign(err, props);
}
throw err;
}
/** Asynchronously fulfill a response with a file from the local file
* system.
*
* If the `options.path` is not supplied, the file to be sent will default
* to this `.request.url.pathname`.
*
* Requires Deno read permission. */
send(options: ContextSendOptions): Promise<string | undefined> {
const { path = this.request.url.pathname, ...sendOptions } = options;
return send(this, path, sendOptions);
}
/** Convert the connection to stream events, returning an event target for
* sending server sent events. Events dispatched on the returned target will
* be sent to the client and be available in the client's `EventSource` that
* initiated the connection.
*
* This will set `.respond` to `false`. */
sendEvents(options?: ServerSentEventTargetOptions): ServerSentEventTarget {
if (this.#sse) {
return this.#sse;
}
this.respond = false;
return this.#sse = new ServerSentEventTarget(
this.app,
this.request.serverRequest,
options,
);
}
/** Create and throw an HTTP Error, which can be used to pass status
* information which can be caught by other middleware to send more
* meaningful error messages back to the client. The passed error status will
* be set on the `.response.status` by default as well.
*/
throw(
errorStatus: ErrorStatus,
message?: string,
props?: Record<string, unknown>,
): never {
const err = createHttpError(errorStatus, message);
if (props) {
Object.assign(err, props);
}
throw err;
}
/** Take the current request and upgrade it to a web socket, resolving with
* the web socket object. This will set `.respond` to `false`. */
async upgrade(): Promise<WebSocket> {
if (this.#socket) {
return this.#socket;
}
const { conn, r: bufReader, w: bufWriter, headers } =
this.request.serverRequest;
this.#socket = await acceptWebSocket(
{ conn, bufReader, bufWriter, headers },
);
this.respond = false;
return this.#socket;
}
}

View File

@ -0,0 +1,15 @@
// Loaded from https://deno.land/x/segno@v1.1.0/lib/validations/isHexadecimal.ts
// @ts-ignore allowing typedoc to build
import { assertString } from '../helpers/assertString.ts';
/**
* @ignore
*/
const hexadecimal = /^(0x|0h)?[0-9A-F]+$/i;
export const isHexadecimal = (str: string) => {
assertString(str);
return hexadecimal.test(str);
};

View File

@ -0,0 +1,34 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/update.js
import _curry3 from './internal/_curry3.js';
import adjust from './adjust.js';
import always from './always.js';
/**
* Returns a new copy of the array with the element at the provided index
* replaced with the given value.
*
* @func
* @memberOf R
* @since v0.14.0
* @category List
* @sig Number -> a -> [a] -> [a]
* @param {Number} idx The index to update.
* @param {*} x The value to exist at the given index of the returned array.
* @param {Array|Arguments} list The source array-like object to be updated.
* @return {Array} A copy of `list` with the value at index `idx` replaced with `x`.
* @see R.adjust
* @example
*
* R.update(1, '_', ['a', 'b', 'c']); //=> ['a', '_', 'c']
* R.update(-1, '_', ['a', 'b', 'c']); //=> ['a', 'b', '_']
* @symb R.update(-1, a, [b, c]) = [b, a]
* @symb R.update(0, a, [b, c]) = [a, c]
* @symb R.update(1, a, [b, c]) = [b, a]
*/
var update = _curry3(function update(idx, x, list) {
return adjust(idx, always(x), list);
});
export default update;

View File

@ -0,0 +1,36 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/median.js
import _curry1 from './internal/_curry1.js';
import mean from './mean.js';
/**
* Returns the median of the given list of numbers.
*
* @func
* @memberOf R
* @since v0.14.0
* @category Math
* @sig [Number] -> Number
* @param {Array} list
* @return {Number}
* @see R.mean
* @example
*
* R.median([2, 9, 7]); //=> 7
* R.median([7, 2, 10, 9]); //=> 8
* R.median([]); //=> NaN
*/
var median = _curry1(function median(list) {
var len = list.length;
if (len === 0) {
return NaN;
}
var width = 2 - len % 2;
var idx = (len - width) / 2;
return mean(Array.prototype.slice.call(list, 0).sort(function(a, b) {
return a < b ? -1 : a > b ? 1 : 0;
}).slice(idx, idx + width));
});
export default median;

View File

@ -0,0 +1,42 @@
// Loaded from https://deno.land/std@0.67.0/path/common.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
/** This module is browser compatible. */
import { SEP } from "./separator.ts";
/** Determines the common path from a set of paths, using an optional separator,
* which defaults to the OS default separator.
*
* import { common } from "https://deno.land/std/path/mod.ts";
* const p = common([
* "./deno/std/path/mod.ts",
* "./deno/std/fs/mod.ts",
* ]);
* console.log(p); // "./deno/std/"
*
*/
export function common(paths: string[], sep = SEP): string {
const [first = "", ...remaining] = paths;
if (first === "" || remaining.length === 0) {
return first.substring(0, first.lastIndexOf(sep) + 1);
}
const parts = first.split(sep);
let endOfPrefix = parts.length;
for (const path of remaining) {
const compare = path.split(sep);
for (let i = 0; i < endOfPrefix; i++) {
if (compare[i] !== parts[i]) {
endOfPrefix = i;
}
}
if (endOfPrefix === 0) {
return "";
}
}
const prefix = parts.slice(0, endOfPrefix).join(sep);
return prefix.endsWith(sep) ? prefix : `${prefix}${sep}`;
}

View File

@ -0,0 +1,10 @@
// Loaded from https://deno.land/x/segno@v1.1.0/lib/validations/isBoolean.ts
// @ts-ignore allowing typedoc to build
import { assertString } from '../helpers/assertString.ts';
export const isBoolean = (str: string) => {
assertString(str);
return ['true', 'false', '1', '0'].indexOf(str) >= 0;
};

View File

@ -0,0 +1,4 @@
// Loaded from https://deno.land/x/mongo@v0.20.0/src/collection/mod.ts
export { Collection } from "./collection.ts";

View File

@ -0,0 +1,42 @@
// Loaded from https://deno.land/std@0.80.0/encoding/_yaml/type/bool.ts
// Ported from js-yaml v3.13.1:
// https://github.com/nodeca/js-yaml/commit/665aadda42349dcae869f12040d9b10ef18d12da
// Copyright 2011-2015 by Vitaly Puzrin. All rights reserved. MIT license.
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { Type } from "../type.ts";
import { isBoolean } from "../utils.ts";
function resolveYamlBoolean(data: string): boolean {
const max = data.length;
return (
(max === 4 && (data === "true" || data === "True" || data === "TRUE")) ||
(max === 5 && (data === "false" || data === "False" || data === "FALSE"))
);
}
function constructYamlBoolean(data: string): boolean {
return data === "true" || data === "True" || data === "TRUE";
}
export const bool = new Type("tag:yaml.org,2002:bool", {
construct: constructYamlBoolean,
defaultStyle: "lowercase",
kind: "scalar",
predicate: isBoolean,
represent: {
lowercase(object: boolean): string {
return object ? "true" : "false";
},
uppercase(object: boolean): string {
return object ? "TRUE" : "FALSE";
},
camelcase(object: boolean): string {
return object ? "True" : "False";
},
},
resolve: resolveYamlBoolean,
});

View File

@ -0,0 +1,32 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/objOf.js
import _curry2 from './internal/_curry2.js';
/**
* Creates an object containing a single key:value pair.
*
* @func
* @memberOf R
* @since v0.18.0
* @category Object
* @sig String -> a -> {String:a}
* @param {String} key
* @param {*} val
* @return {Object}
* @see R.pair
* @example
*
* const matchPhrases = R.compose(
* R.objOf('must'),
* R.map(R.objOf('match_phrase'))
* );
* matchPhrases(['foo', 'bar', 'baz']); //=> {must: [{match_phrase: 'foo'}, {match_phrase: 'bar'}, {match_phrase: 'baz'}]}
*/
var objOf = _curry2(function objOf(key, val) {
var obj = {};
obj[key] = val;
return obj;
});
export default objOf;

View File

@ -0,0 +1,35 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/partialObject.js
import mergeDeepRight from './mergeDeepRight.js';
import _curry2 from './internal/_curry2.js';
/**
* Takes a function `f` and an object, and returns a function `g`.
* When applied, `g` returns the result of applying `f` to the object
* provided initially merged deeply (right) with the object provided as an argument to `g`.
*
* @func
* @memberOf R
* @category Function
* @sig (({ a, b, c, ..., n }) -> x) -> { a, b, c, ...} -> ({ d, e, f, ..., n } -> x)
* @param {Function} f
* @param {Object} props
* @return {Function}
* @see R.partial, R.partialRight, R.curry, R.mergeDeepRight
* @example
*
* const multiply2 = ({ a, b }) => a * b;
* const double = R.partialObject(multiply2, { a: 2 });
* double({ b: 2 }); //=> 4
*
* const greet = ({ salutation, title, firstName, lastName }) =>
* salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!';
*
* const sayHello = R.partialObject(greet, { salutation: 'Hello' });
* const sayHelloToMs = R.partialObject(sayHello, { title: 'Ms.' });
* sayHelloToMs({ firstName: 'Jane', lastName: 'Jones' }); //=> 'Hello, Ms. Jane Jones!'
* @symb R.partialObject(f, { a, b })({ c, d }) = f({ a, b, c, d })
*/
export default _curry2((f, o) => (props) => f.call(this, mergeDeepRight(o, props)));

View File

@ -0,0 +1,8 @@
// Loaded from https://deno.land/x/graphql_deno@v15.0.0/lib/polyfills/objectValues.js
/* eslint-disable no-redeclare */
// $FlowFixMe workaround for: https://github.com/facebook/flow/issues/2221
const objectValues = Object.values || (obj => Object.keys(obj).map(key => obj[key]));
export default objectValues;

View File

@ -0,0 +1,77 @@
// Loaded from https://deno.land/x/graphql_deno@v15.0.0/lib/utilities/separateOperations.js
import { Kind } from '../language/kinds.js';
import { visit } from '../language/visitor.js';
/**
* separateOperations accepts a single AST document which may contain many
* operations and fragments and returns a collection of AST documents each of
* which contains a single operation as well the fragment definitions it
* refers to.
*/
export function separateOperations(documentAST) {
const operations = [];
const depGraph = Object.create(null);
let fromName; // Populate metadata and build a dependency graph.
visit(documentAST, {
OperationDefinition(node) {
fromName = opName(node);
operations.push(node);
},
FragmentDefinition(node) {
fromName = node.name.value;
},
FragmentSpread(node) {
const toName = node.name.value;
let dependents = depGraph[fromName];
if (dependents === undefined) {
dependents = depGraph[fromName] = Object.create(null);
}
dependents[toName] = true;
}
}); // For each operation, produce a new synthesized AST which includes only what
// is necessary for completing that operation.
const separatedDocumentASTs = Object.create(null);
for (const operation of operations) {
const operationName = opName(operation);
const dependencies = Object.create(null);
collectTransitiveDependencies(dependencies, depGraph, operationName); // The list of definition nodes to be included for this operation, sorted
// to retain the same order as the original document.
separatedDocumentASTs[operationName] = {
kind: Kind.DOCUMENT,
definitions: documentAST.definitions.filter(node => node === operation || node.kind === Kind.FRAGMENT_DEFINITION && dependencies[node.name.value])
};
}
return separatedDocumentASTs;
}
// Provides the empty string for anonymous operations.
function opName(operation) {
return operation.name ? operation.name.value : '';
} // From a dependency graph, collects a list of transitive dependencies by
// recursing through a dependency graph.
function collectTransitiveDependencies(collected, depGraph, fromName) {
const immediateDeps = depGraph[fromName];
if (immediateDeps) {
for (const toName of Object.keys(immediateDeps)) {
if (!collected[toName]) {
collected[toName] = true;
collectTransitiveDependencies(collected, depGraph, toName);
}
}
}
}

View File

@ -0,0 +1,205 @@
// Loaded from https://deno.land/x/deno_image@v0.0.3/lib/decoders/fast-png/PNGEncoder.ts
import { IOBuffer } from './iobuffer/IOBuffer.ts';
import { deflate } from './pako/index.js';
import { pngSignature, crc } from './common.ts';
import {
DeflateFunctionOptions,
IPNGEncoderOptions,
IImageData,
IDecodedPNG,
PNGDataArray,
BitDepth,
} from './types.ts';
import {
ColorType,
CompressionMethod,
FilterMethod,
InterlaceMethod,
} from './internalTypes.ts';
const defaultZlibOptions: DeflateFunctionOptions = {
level: 3,
};
export default class PNGEncoder extends IOBuffer {
private _png: IDecodedPNG;
private _zlibOptions: DeflateFunctionOptions;
private _colorType: ColorType;
public constructor(data: IImageData, options: IPNGEncoderOptions = {}) {
super();
this._colorType = ColorType.UNKNOWN;
this._zlibOptions = Object.assign({}, defaultZlibOptions, options.zlib);
this._png = this._checkData(data);
this.setBigEndian();
}
public encode(): Uint8Array {
this.encodeSignature();
this.encodeIHDR();
this.encodeData();
this.encodeIEND();
return this.toArray();
}
// https://www.w3.org/TR/PNG/#5PNG-file-signature
private encodeSignature(): void {
this.writeBytes(pngSignature);
}
// https://www.w3.org/TR/PNG/#11IHDR
private encodeIHDR(): void {
this.writeUint32(13);
this.writeChars('IHDR');
this.writeUint32(this._png.width);
this.writeUint32(this._png.height);
this.writeByte(this._png.depth);
this.writeByte(this._colorType);
this.writeByte(CompressionMethod.DEFLATE);
this.writeByte(FilterMethod.ADAPTIVE);
this.writeByte(InterlaceMethod.NO_INTERLACE);
this.writeCrc(17);
}
// https://www.w3.org/TR/PNG/#11IEND
private encodeIEND(): void {
this.writeUint32(0);
this.writeChars('IEND');
this.writeCrc(4);
}
// https://www.w3.org/TR/PNG/#11IDAT
private encodeIDAT(data: PNGDataArray): void {
this.writeUint32(data.length);
this.writeChars('IDAT');
this.writeBytes(data);
this.writeCrc(data.length + 4);
}
private encodeData(): void {
const { width, height, channels, depth, data } = this._png;
const slotsPerLine = channels * width;
const newData = new IOBuffer().setBigEndian();
let offset = 0;
for (let i = 0; i < height; i++) {
newData.writeByte(0); // no filter
/* istanbul ignore else */
if (depth === 8) {
offset = writeDataBytes(data, newData, slotsPerLine, offset);
} else if (depth === 16) {
offset = writeDataUint16(data, newData, slotsPerLine, offset);
} else {
throw new Error('unreachable');
}
}
const buffer = newData.toArray();
const compressed = <Uint8Array>deflate(buffer, this._zlibOptions);
this.encodeIDAT(compressed);
}
private _checkData(data: IImageData): IDecodedPNG {
const { colorType, channels, depth } = getColorType(data);
const png: IDecodedPNG = {
width: checkInteger(data.width, 'width'),
height: checkInteger(data.height, 'height'),
channels: channels,
data: data.data,
depth: depth,
text: {},
};
this._colorType = colorType;
const expectedSize = png.width * png.height * channels;
if (png.data.length !== expectedSize) {
throw new RangeError(
`wrong data size. Found ${png.data.length}, expected ${expectedSize}`,
);
}
return png;
}
private writeCrc(length: number): void {
this.writeUint32(
crc(
new Uint8Array(
this.buffer,
this.byteOffset + this.offset - length,
length,
),
length,
),
);
}
}
function checkInteger(value: number, name: string): number {
if (Number.isInteger(value) && value > 0) {
return value;
}
throw new TypeError(`${name} must be a positive integer`);
}
function getColorType(
data: IImageData,
): { channels: number; depth: BitDepth; colorType: ColorType } {
const { channels = 4, depth = 8 } = data;
if (channels !== 4 && channels !== 3 && channels !== 2 && channels !== 1) {
throw new RangeError(`unsupported number of channels: ${channels}`);
}
if (depth !== 8 && depth !== 16) {
throw new RangeError(`unsupported bit depth: ${depth}`);
}
const returnValue = { channels, depth, colorType: ColorType.UNKNOWN };
switch (channels) {
case 4:
returnValue.colorType = ColorType.TRUECOLOUR_ALPHA;
break;
case 3:
returnValue.colorType = ColorType.TRUECOLOUR;
break;
case 1:
returnValue.colorType = ColorType.GREYSCALE;
break;
case 2:
returnValue.colorType = ColorType.GREYSCALE_ALPHA;
break;
default:
throw new Error(`unsupported number of channels: ${channels}`);
}
return returnValue;
}
function writeDataBytes(
data: PNGDataArray,
newData: IOBuffer,
slotsPerLine: number,
offset: number,
): number {
for (let j = 0; j < slotsPerLine; j++) {
newData.writeByte(data[offset++]);
}
return offset;
}
function writeDataUint16(
data: PNGDataArray,
newData: IOBuffer,
slotsPerLine: number,
offset: number,
): number {
for (let j = 0; j < slotsPerLine; j++) {
newData.writeUint16(data[offset++]);
}
return offset;
}

View File

@ -0,0 +1,51 @@
// Loaded from https://deno.land/x/ramda@v0.27.2/source/mergeWithKey.js
import _curry3 from './internal/_curry3.js';
import _has from './internal/_has.js';
/**
* Creates a new object with the own properties of the two provided objects. If
* a key exists in both objects, the provided function is applied to the key
* and the values associated with the key in each object, with the result being
* used as the value associated with the key in the returned object.
*
* @func
* @memberOf R
* @since v0.19.0
* @category Object
* @sig ((String, a, a) -> a) -> {a} -> {a} -> {a}
* @param {Function} fn
* @param {Object} l
* @param {Object} r
* @return {Object}
* @see R.mergeDeepWithKey, R.merge, R.mergeWith
* @example
*
* let concatValues = (k, l, r) => k == 'values' ? R.concat(l, r) : r
* R.mergeWithKey(concatValues,
* { a: true, thing: 'foo', values: [10, 20] },
* { b: true, thing: 'bar', values: [15, 35] });
* //=> { a: true, b: true, thing: 'bar', values: [10, 20, 15, 35] }
* @symb R.mergeWithKey(f, { x: 1, y: 2 }, { y: 5, z: 3 }) = { x: 1, y: f('y', 2, 5), z: 3 }
*/
var mergeWithKey = _curry3(function mergeWithKey(fn, l, r) {
var result = {};
var k;
for (k in l) {
if (_has(k, l)) {
result[k] = _has(k, r) ? fn(k, l[k], r[k]) : l[k];
}
}
for (k in r) {
if (_has(k, r) && !(_has(k, result))) {
result[k] = r[k];
}
}
return result;
});
export default mergeWithKey;

View File

@ -0,0 +1,4 @@
// Loaded from https://deno.land/x/abc@v1.2.4/vendor/https/deno.land/std/mime/multipart.ts
export * from "https://deno.land/std@0.81.0/mime/multipart.ts";

View File

@ -0,0 +1,13 @@
// Loaded from https://deno.land/x/case/titleCase.ts
import upperCase from "./upperCase.ts";
import normalCase from "./normalCase.ts";
export default function titleCase(value: string, locale?: string): string {
return normalCase(value, locale).replace(/^.| ./g, function (
m: string,
): string {
return upperCase(m, locale);
});
}

View File

@ -0,0 +1,65 @@
// Loaded from https://deno.land/std@0.67.0/path/_constants.ts
// Copyright the Browserify authors. MIT License.
// Ported from https://github.com/browserify/path-browserify/
/** This module is browser compatible. */
// Alphabet chars.
export const CHAR_UPPERCASE_A = 65; /* A */
export const CHAR_LOWERCASE_A = 97; /* a */
export const CHAR_UPPERCASE_Z = 90; /* Z */
export const CHAR_LOWERCASE_Z = 122; /* z */
// Non-alphabetic chars.
export const CHAR_DOT = 46; /* . */
export const CHAR_FORWARD_SLASH = 47; /* / */
export const CHAR_BACKWARD_SLASH = 92; /* \ */
export const CHAR_VERTICAL_LINE = 124; /* | */
export const CHAR_COLON = 58; /* : */
export const CHAR_QUESTION_MARK = 63; /* ? */
export const CHAR_UNDERSCORE = 95; /* _ */
export const CHAR_LINE_FEED = 10; /* \n */
export const CHAR_CARRIAGE_RETURN = 13; /* \r */
export const CHAR_TAB = 9; /* \t */
export const CHAR_FORM_FEED = 12; /* \f */
export const CHAR_EXCLAMATION_MARK = 33; /* ! */
export const CHAR_HASH = 35; /* # */
export const CHAR_SPACE = 32; /* */
export const CHAR_NO_BREAK_SPACE = 160; /* \u00A0 */
export const CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279; /* \uFEFF */
export const CHAR_LEFT_SQUARE_BRACKET = 91; /* [ */
export const CHAR_RIGHT_SQUARE_BRACKET = 93; /* ] */
export const CHAR_LEFT_ANGLE_BRACKET = 60; /* < */
export const CHAR_RIGHT_ANGLE_BRACKET = 62; /* > */
export const CHAR_LEFT_CURLY_BRACKET = 123; /* { */
export const CHAR_RIGHT_CURLY_BRACKET = 125; /* } */
export const CHAR_HYPHEN_MINUS = 45; /* - */
export const CHAR_PLUS = 43; /* + */
export const CHAR_DOUBLE_QUOTE = 34; /* " */
export const CHAR_SINGLE_QUOTE = 39; /* ' */
export const CHAR_PERCENT = 37; /* % */
export const CHAR_SEMICOLON = 59; /* ; */
export const CHAR_CIRCUMFLEX_ACCENT = 94; /* ^ */
export const CHAR_GRAVE_ACCENT = 96; /* ` */
export const CHAR_AT = 64; /* @ */
export const CHAR_AMPERSAND = 38; /* & */
export const CHAR_EQUAL = 61; /* = */
// Digits
export const CHAR_0 = 48; /* 0 */
export const CHAR_9 = 57; /* 9 */
let NATIVE_OS: typeof Deno.build.os = "linux";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const navigator = (globalThis as any).navigator;
if (globalThis.Deno != null) {
NATIVE_OS = Deno.build.os;
} else if (navigator?.appVersion?.includes?.("Win") ?? false) {
NATIVE_OS = "windows";
}
// TODO(nayeemrmn): Improve OS detection in browsers beyond Windows.
export const isWindows = NATIVE_OS == "windows";
export { NATIVE_OS };

View File

@ -0,0 +1,150 @@
// Loaded from https://deno.land/x/god_crypto@v1.4.3/src/rsa/rsa_internal.ts
import { power_mod } from "./../math.ts";
import { eme_oaep_encode, eme_oaep_decode } from "./eme_oaep.ts";
import { os2ip, i2osp } from "./primitives.ts";
import { concat, random_bytes } from "./../helper.ts";
import { ber_decode, ber_simple } from "./basic_encoding_rule.ts";
import { RawBinary } from "../binary.ts";
/**
* @param n public key modulus
* @param e public key exponent
* @param m message representative
*/
export function rsaep(n: bigint, e: bigint, m: bigint): bigint {
return power_mod(m, e, n);
}
/**
* @param n private key modulus
* @param d private key exponent
* @param c ciphertext representative
*/
export function rsadp(n: bigint, d: bigint, c: bigint): bigint {
return power_mod(c, d, n);
}
export function rsa_oaep_encrypt(
bytes: number,
n: bigint,
e: bigint,
m: Uint8Array,
algorithm: "sha1" | "sha256",
) {
const em = eme_oaep_encode(new Uint8Array(0), m, bytes, algorithm);
const msg = os2ip(em);
const c = rsaep(n, e, msg);
return i2osp(c, bytes);
}
export function rsa_oaep_decrypt(
bytes: number,
n: bigint,
d: bigint,
c: Uint8Array,
algorithm: "sha1" | "sha256",
) {
const em = rsadp(n, d, os2ip(c));
const m = eme_oaep_decode(
new Uint8Array(0),
i2osp(em, bytes),
bytes,
algorithm,
);
return m;
}
export function rsa_pkcs1_encrypt(
bytes: number,
n: bigint,
e: bigint,
m: Uint8Array,
) {
const p = concat([0x00, 0x02], random_bytes(bytes - m.length - 3), [0x00], m);
const msg = os2ip(p);
const c = rsaep(n, e, msg);
return i2osp(c, bytes);
}
export function rsa_pkcs1_decrypt(
bytes: number,
n: bigint,
d: bigint,
c: Uint8Array,
) {
const em = i2osp(rsadp(n, d, os2ip(c)), bytes);
if (em[0] !== 0) throw "Decryption error";
if (em[1] !== 0x02) throw "Decryption error";
let psCursor = 2;
for (; psCursor < em.length; psCursor++) {
if (em[psCursor] === 0x00) break;
}
if (psCursor < 10) throw "Decryption error";
return em.slice(psCursor + 1);
}
export function rsa_pkcs1_verify(
bytes: number,
n: bigint,
d: bigint,
s: Uint8Array,
m: Uint8Array,
): boolean {
let em = i2osp(rsadp(n, d, os2ip(s)), bytes);
if (em[0] !== 0) throw "Decryption error";
if (em[1] !== 0x01) throw "Decryption error";
let psCursor = 2;
for (; psCursor < em.length; psCursor++) {
if (em[psCursor] === 0x00) break;
}
if (psCursor < 10) throw "Decryption error";
// Removing padding
em = em.slice(psCursor + 1);
// Parsing the BER
const ber: [[number, null], Uint8Array] = ber_simple(ber_decode(em)) as any;
const decryptedMessage = ber[1];
// Comparing the value
if (decryptedMessage.length !== m.length) return false;
for (let i = 0; i < decryptedMessage.length; i++) {
if (decryptedMessage[i] !== m[i]) return false;
}
return true;
}
export function rsa_pkcs1_sign(
bytes: number,
n: bigint,
d: bigint,
message: Uint8Array,
): RawBinary {
// deno-fmt-ignore
const oid = [0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00]
const der = [
0x30,
message.length + 2 + oid.length,
...oid,
0x04,
message.length,
...message,
];
const ps = new Array(bytes - 3 - der.length).fill(0xff);
const em = new Uint8Array([0x00, 0x01, ...ps, 0x00, ...der]);
const msg = os2ip(em);
const c = rsaep(n, d, msg);
return new RawBinary(i2osp(c, bytes));
}

View File

@ -0,0 +1,18 @@
// Loaded from https://deno.land/std@0.80.0/_util/assert.ts
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
export class DenoStdInternalError extends Error {
constructor(message: string) {
super(message);
this.name = "DenoStdInternalError";
}
}
/** Make an assertion, if not `true`, then throw. */
export function assert(expr: unknown, msg = ""): asserts expr {
if (!expr) {
throw new DenoStdInternalError(msg);
}
}

View File

@ -0,0 +1,14 @@
// Loaded from https://deno.land/x/deno_image@v0.0.3/lib/decoders/fast-png/iobuffer/utf8.ts
const decoder = new TextDecoder('utf-8');
export function decode(bytes: Uint8Array): string {
return decoder.decode(bytes);
}
const encoder = new TextEncoder();
export function encode(str: string): Uint8Array {
return encoder.encode(str);
}

Some files were not shown because too many files have changed in this diff Show More