summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Beliaev2023-08-01 19:34:48 +1200
committerAleksandr Beliaev2023-08-01 19:34:48 +1200
commitc6a9ec9caceac36ab1a195bce0a0a603aa3844f2 (patch)
tree40c72fce726aa9281bf4f2f680bdb04a8c3685a4
parenta00cc041126a133f08b8c365b70ef85e596c86a6 (diff)
downloadaur-c6a9ec9caceac36ab1a195bce0a0a603aa3844f2.tar.gz
v1.4.274.r2.gd9c08cbc9
-rw-r--r--.SRCINFO11
-rw-r--r--001_vendor_patch_1.diff1672
-rw-r--r--001_vendor_patch_2.diff33
-rw-r--r--002_multi_def_patch_1.diff11
-rw-r--r--002_multi_def_patch_2.diff11
-rw-r--r--PKGBUILD68
6 files changed, 1781 insertions, 25 deletions
diff --git a/.SRCINFO b/.SRCINFO
index e98ec8218707..cac0a9dddbfe 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,6 +1,6 @@
pkgbase = quarto-cli-git
pkgdesc = Quarto is an open-source scientific and technical publishing system built on [Pandoc](https://pandoc.org). This package tracks main git branch of Quarto.
- pkgver = 1.4.96.r1.gf23b0ad34
+ pkgver = 1.4.274.r2.gd9c08cbc9
pkgrel = 1
url = https://quarto.org/
arch = x86_64
@@ -15,6 +15,7 @@ pkgbase = quarto-cli-git
depends = esbuild
depends = pandoc
depends = lua-lpeg
+ depends = typst
provides = quarto
conflicts = quarto-cli-bin
conflicts = quarto-cli
@@ -24,9 +25,17 @@ pkgbase = quarto-cli-git
source = https://github.com/b-fuze/deno-dom/archive/refs/tags/v0.1.35-alpha-artifacts.tar.gz
source = https://github.com/c4spar/deno-cliffy/archive/refs/tags/v0.25.7.tar.gz
source = https://github.com/denoland/deno_std/archive/refs/tags/0.170.0.tar.gz
+ source = 001_vendor_patch_1.diff
+ source = 001_vendor_patch_2.diff
+ source = 002_multi_def_patch_1.diff
+ source = 002_multi_def_patch_2.diff
sha256sums = SKIP
sha256sums = 14fb042a6912041b9fda91fd643cf278764d075bc9539aa1e107475915cd896c
sha256sums = 519709be1dfcf4743930b7f21a513d8fbf3663380020eac8ba629081395f6cc0
sha256sums = 369bc68b848532bedcb786a8fce5e52000624b9262f05ceeeb16bc851b6cf752
+ sha256sums = 937a39f116c4310c4989cf71b9e174b6dc7bfdd84c6632e5dd0b47508cffef86
+ sha256sums = 144101b799267869395ba2fe85ab8549be277b18af9545c106675f620e73a85b
+ sha256sums = 6c1adcf6a21ab6a2949eee9770fe19ef453758dc2e1d3f7a071f07c66d5c92b2
+ sha256sums = 1ee399808579aa05f38b9c27dfd23e9102f38fffb437233d360b0c076118312f
pkgname = quarto-cli-git
diff --git a/001_vendor_patch_1.diff b/001_vendor_patch_1.diff
new file mode 100644
index 000000000000..ea8c8ca8c9c0
--- /dev/null
+++ b/001_vendor_patch_1.diff
@@ -0,0 +1,1672 @@
+diff -Nru quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v4.1.4/cookie_jar.ts quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v4.1.4/cookie_jar.ts
+--- quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v4.1.4/cookie_jar.ts 2023-07-22 08:39:00.000000000 +1200
++++ quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v4.1.4/cookie_jar.ts 1970-01-01 12:00:00.000000000 +1200
+@@ -1,259 +0,0 @@
+-import {
+- Cookie,
+- CookieOptions,
+- isSameDomainOrSubdomain,
+- parseURL,
+-} from "./cookie.ts";
+-
+-const strictMatchProps = [
+- "value",
+- "secure",
+- "httpOnly",
+- "maxAge",
+- "expires",
+- "sameSite",
+-];
+-
+-function cookieMatches(
+- options: Cookie | CookieOptions,
+- comparedWith: Cookie,
+- strictMatch = false,
+-): boolean {
+- if (
+- options.path !== undefined && !comparedWith.path?.startsWith(options.path)
+- ) {
+- return false;
+- }
+-
+- if (options.domain) {
+- if (!isSameDomainOrSubdomain(options.domain, comparedWith.domain)) {
+- return false;
+- }
+- }
+-
+- if (
+- options.name !== undefined &&
+- options.name !== comparedWith.name
+- ) {
+- return false;
+- }
+-
+- if (
+- strictMatch &&
+- strictMatchProps.some((propKey) =>
+- // deno-lint-ignore ban-ts-comment
+- // @ts-ignore
+- options[propKey] !== undefined &&
+- // deno-lint-ignore ban-ts-comment
+- // @ts-ignore
+- options[propKey] !== comparedWith[propKey]
+- )
+- ) {
+- return false;
+- }
+-
+- return true;
+-}
+-
+-// cookie compare from tough-cookie
+-const MAX_TIME = 2147483647000; // 31-bit max
+-/**
+- * Cookies with longer paths are listed before cookies with
+- * shorter paths.
+- *
+- * Among cookies that have equal-length path fields, cookies with
+- * earlier creation-times are listed before cookies with later
+- * creation-times."
+- */
+-function cookieCompare(a: Cookie, b: Cookie) {
+- let cmp = 0;
+-
+- // descending for length: b CMP a
+- const aPathLen = a.path?.length || 0;
+- const bPathLen = b.path?.length || 0;
+- cmp = bPathLen - aPathLen;
+- if (cmp !== 0) {
+- return cmp;
+- }
+-
+- // ascending for time: a CMP b
+- const aTime = a.creationDate || MAX_TIME;
+- const bTime = b.creationDate || MAX_TIME;
+- cmp = aTime - bTime;
+- if (cmp !== 0) {
+- return cmp;
+- }
+-
+- // tie breaker
+- cmp = a.creationIndex - b.creationIndex;
+-
+- return cmp;
+-}
+-
+-export class CookieJar {
+- cookies = Array<Cookie>();
+-
+- /**
+- * @param cookies - the cookies array to initialize with
+- */
+- constructor(cookies?: Array<Cookie> | Array<CookieOptions>) {
+- this.replaceCookies(cookies);
+- }
+-
+- /**
+- * Sets or replaces a cookie inside the jar.
+- * Only sets new cookies if cookie is valid and not expired.
+- * Validation and expiration checks are not run when replacing a cookie.
+- * @param url - the url that this cookie from received from. mainly used by the fetch wrapper.
+- * will automatically set domain and path if provided and it was not found inside Cookie/cookiestring.
+- */
+- setCookie(cookie: Cookie | string, url?: string | Request | URL) {
+- let cookieObj;
+- if (typeof cookie === "string") {
+- cookieObj = Cookie.from(cookie);
+- } else {
+- cookieObj = cookie;
+- }
+- if (url) {
+- if (!cookieObj.domain) {
+- cookieObj.setDomain(url);
+- }
+- if (!cookieObj.path) {
+- cookieObj.setPath(url);
+- }
+- }
+-
+- if (!cookieObj.isValid()) {
+- return;
+- }
+-
+- const foundCookie = this.getCookie(cookieObj);
+- if (foundCookie) {
+- const indexOfCookie = this.cookies.indexOf(foundCookie);
+- if (!cookieObj.isExpired()) {
+- this.cookies.splice(indexOfCookie, 1, cookieObj);
+- } else {
+- this.cookies.splice(indexOfCookie, 1);
+- }
+- } else if (!cookieObj.isExpired()) {
+- this.cookies.push(cookieObj);
+- }
+-
+- // sort by creation date, so when searching, we get the latest created cookies.
+- this.cookies.sort(cookieCompare);
+- }
+-
+- /**
+- * Gets the first cooking matching the defined properties of a given Cookie or CookieOptions.
+- * returns undefined if not found or expired. `creationDate` prop is not checked.
+- * Also removes the cookie and returns undefined if cookie is expired.
+- */
+- getCookie(options: Cookie | CookieOptions): Cookie | undefined {
+- const strictMatch = typeof (options as Cookie).isValid !== "function";
+- for (const [index, cookie] of this.cookies.entries()) {
+- if (cookieMatches(options, cookie, strictMatch)) {
+- if (!cookie.isExpired()) {
+- return cookie;
+- } else {
+- this.cookies.splice(index, 1);
+- return undefined;
+- }
+- }
+- }
+- }
+-
+- /**
+- * returnes cookies that matches the options excluding expired ones, also removes expired cookies before returning.
+- * @param options - the options to filter cookies with, and if not provided, returnes all cookies.
+- * if no cookie is found with given options, an empty array is returned.
+- */
+- getCookies(options?: CookieOptions | Cookie) {
+- if (options) {
+- const matchedCookies: Cookie[] = [];
+- const removeCookies: Cookie[] = [];
+- for (const cookie of this.cookies) {
+- if (cookieMatches(options, cookie)) {
+- if (!cookie.isExpired()) {
+- matchedCookies.push(cookie);
+- } else {
+- removeCookies.push(cookie);
+- }
+- }
+- }
+- if (removeCookies.length) {
+- this.cookies = this.cookies.filter((cookie) =>
+- !removeCookies.includes(cookie)
+- );
+- }
+- return matchedCookies;
+- } else {
+- return this.cookies;
+- }
+- }
+-
+- getCookieString(url: string | Request | URL) {
+- const searchCookie = new Cookie();
+- searchCookie.setDomain(url);
+- const cookiesToSend = this.getCookies(searchCookie)
+- .filter((cookie) => {
+- return cookie.canSendTo(parseURL(url));
+- })
+- .map((c) => c.getCookieString())
+- .join("; ");
+- return cookiesToSend;
+- }
+-
+- toJSON() {
+- return this.cookies;
+- }
+-
+- /**
+- * Removes first cookie that matches the given option.
+- *
+- * Returns the deleted cookie if found or undefined otherwise.
+- */
+- removeCookie(options: CookieOptions | Cookie): Cookie | undefined {
+- for (const [index, cookie] of this.cookies.entries()) {
+- if (cookieMatches(options, cookie)) {
+- return this.cookies.splice(index, 1)[0];
+- }
+- }
+- }
+-
+- /**
+- * Removes all cookies that matches the given option.
+- * If options is not given, all cookies will be deleted.
+- *
+- * Returns the deleted cookies if found or undefined otherwise.
+- */
+- removeCookies(options?: CookieOptions | Cookie): Array<Cookie> | undefined {
+- if (options) {
+- const deletedCookies: Cookie[] = [];
+- this.cookies = this.cookies.filter((cookie) => {
+- if (cookieMatches(options, cookie)) {
+- deletedCookies.push(cookie);
+- return false;
+- }
+- return true;
+- });
+- return deletedCookies.length ? deletedCookies : undefined;
+- } else {
+- this.cookies = [];
+- }
+- }
+-
+- replaceCookies(cookies?: Array<Cookie> | Array<CookieOptions>) {
+- if (cookies?.length) {
+- if (typeof (cookies[0] as Cookie).isValid === "function") {
+- this.cookies = cookies as Array<Cookie>;
+- } else {
+- this.cookies = [];
+- for (const option of cookies) {
+- this.cookies.push(new Cookie(option));
+- }
+- }
+- } else {
+- this.cookies = [];
+- }
+- }
+-}
+diff -Nru quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v4.1.4/cookie.ts quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v4.1.4/cookie.ts
+--- quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v4.1.4/cookie.ts 2023-07-22 08:39:00.000000000 +1200
++++ quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v4.1.4/cookie.ts 1970-01-01 12:00:00.000000000 +1200
+@@ -1,450 +0,0 @@
+-// import { } from "./deps.ts";
+-
+-// deno-lint-ignore no-control-regex
+-const CONTROL_CHARS = /[\x00-\x1F\x7F]/;
+-
+-// with help from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie and rfc6265
+-const COOKIE_NAME_BLOCKED = /[()<>@,;:\\"/[\]?={}]/;
+-
+-// cookie octet should not have control characters, Whitespace, double quotes, comma, semicolon, and backslash
+-const COOKIE_OCTET_BLOCKED = /[\s",;\\]/;
+-const COOKIE_OCTET = /^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]+$/;
+-
+-const TERMINATORS = ["\n", "\r", "\0"];
+-
+-/**
+- * does not make a difference which one is domainA or domainB
+- *
+- * according to https://stackoverflow.com/a/30676300/3542461
+- */
+-export function isSameDomainOrSubdomain(domainA?: string, domainB?: string) {
+- if (!domainA || !domainB) {
+- return false;
+- }
+-
+- let longerDomain;
+- let shorterDomain;
+- if (domainB.length > domainA.length) {
+- longerDomain = domainB;
+- shorterDomain = domainA;
+- } else {
+- longerDomain = domainA;
+- shorterDomain = domainB;
+- }
+-
+- // check if it's a subdomain or only partially matched
+- const indexOfDomain = longerDomain.indexOf(shorterDomain);
+- if (indexOfDomain === -1) {
+- return false;
+- } else if (indexOfDomain > 0) {
+- // if the character behind the part is not a dot, its not a subdomain
+- if (longerDomain.charAt(indexOfDomain - 1) !== ".") {
+- return false;
+- }
+- }
+- // indexOfDomain === 0 is valid
+-
+- return true;
+-}
+-
+-// from tough-cookie
+-function trimTerminator(str: string) {
+- if (str === undefined || str === "") return str;
+- for (let t = 0; t < TERMINATORS.length; t++) {
+- const terminatorIdx = str.indexOf(TERMINATORS[t]);
+- if (terminatorIdx !== -1) {
+- str = str.substr(0, terminatorIdx);
+- }
+- }
+-
+- return str;
+-}
+-
+-function isValidName(name: string | undefined) {
+- if (!name) {
+- return false;
+- }
+- if (CONTROL_CHARS.test(name) || COOKIE_NAME_BLOCKED.test(name)) {
+- return false;
+- }
+- return true;
+-}
+-
+-function trimWrappingDoubleQuotes(val: string) {
+- // the value can be wrapped in double quotes, but can't contain double quotes within the value
+- if (val.length >= 2 && val.at(0) === '"' && val.at(-1) === '"') {
+- return val.slice(1, -1);
+- }
+- return val;
+-}
+-
+-function isValidValue(val: string | undefined) {
+- if (val === "") {
+- return true;
+- }
+- if (!val) {
+- return false;
+- }
+- if (
+- CONTROL_CHARS.test(val) ||
+- COOKIE_OCTET_BLOCKED.test(val) ||
+- !COOKIE_OCTET.test(val)
+- ) {
+- return false;
+- }
+-
+- return true;
+-}
+-
+-export function parseURL(input: string | Request | URL) {
+- let copyUrl: string;
+- if (input instanceof Request) {
+- copyUrl = input.url;
+- } else if (input instanceof URL) {
+- copyUrl = input.toString();
+- } else {
+- copyUrl = input;
+- }
+- // we *need* to replace the leading dot to simplify usage and expectations
+- copyUrl = copyUrl.replace(/^\./, "");
+- if (!copyUrl.includes("://")) {
+- // the protocol does not matter, but we default to insecure for use inside canSendTo
+- copyUrl = "http://" + copyUrl;
+- }
+- return new URL(copyUrl);
+-}
+-
+-export type CookieOptions = {
+- name?: string;
+- value?: string;
+- path?: string;
+- domain?: string;
+- /** in milliseconds */
+- expires?: number;
+- /** in seconds */
+- maxAge?: number;
+- secure?: boolean;
+- httpOnly?: boolean;
+- sameSite?: "Lax" | "Strict" | "None";
+- /** used for checking against maxAge */
+- creationDate?: number;
+-};
+-
+-export class Cookie {
+- // important
+- name: string | undefined;
+- value: string | undefined;
+- path: string | undefined;
+- domain: string | undefined;
+- // expire
+- /** in milliseconds */
+- expires: number | undefined;
+- /** in seconds */
+- maxAge: number | undefined;
+- // other
+- secure: boolean | undefined;
+- httpOnly: boolean | undefined;
+- sameSite: "Lax" | "Strict" | "None" | undefined;
+- creationDate = Date.now();
+- // deno-lint-ignore ban-ts-comment
+- // @ts-ignore
+- creationIndex: number;
+-
+- static cookiesCreated = 0;
+-
+- constructor(options?: CookieOptions) {
+- if (options) {
+- this.name = options.name;
+- this.value = options.value;
+- this.path = options.path;
+- this.domain = options.domain;
+- this.expires = options.expires;
+- this.maxAge = options.maxAge;
+- this.secure = options.secure;
+- this.httpOnly = options.httpOnly;
+- this.sameSite = options.sameSite;
+-
+- if (options.creationDate) {
+- this.creationDate = options.creationDate;
+- }
+- }
+-
+- // used to break creation ties in cookieCompare():
+- Object.defineProperty(this, "creationIndex", {
+- configurable: false,
+- enumerable: false, // important for assertStrictEquals checks
+- writable: true,
+- value: ++Cookie.cookiesCreated,
+- });
+- }
+-
+- static from(cookieStr: string) {
+- const options = {
+- name: undefined,
+- value: undefined,
+- path: undefined,
+- domain: undefined,
+- expires: undefined,
+- maxAge: undefined,
+- secure: undefined,
+- httpOnly: undefined,
+- sameSite: undefined,
+- creationDate: Date.now(),
+- } as CookieOptions;
+-
+- const unparsed = cookieStr.slice().trim(); // copy
+- const attrAndValueList = unparsed.split(";");
+-
+- // first split is the key value pair,
+- // if theres no semicolon in the string, still the first element in array is key value pair
+- const keyValuePairString = trimTerminator(attrAndValueList.shift() || "")
+- .trim();
+- const keyValuePairEqualsIndex = keyValuePairString.indexOf("=");
+- if (keyValuePairEqualsIndex < 0) {
+- return new Cookie();
+- }
+- const name = keyValuePairString.slice(0, keyValuePairEqualsIndex);
+- const value = trimWrappingDoubleQuotes(
+- keyValuePairString.slice(keyValuePairEqualsIndex + 1),
+- );
+-
+- if (!(isValidName(name) && isValidValue(value))) {
+- return new Cookie();
+- }
+- options.name = name;
+- options.value = value;
+-
+- // now get attributes
+- while (attrAndValueList.length) {
+- const cookieAV = attrAndValueList.shift()?.trim();
+- if (!cookieAV) {
+- // invalid attribute length
+- continue;
+- }
+-
+- const avSeperatorIndex = cookieAV.indexOf("=");
+- let attrKey, attrValue;
+-
+- if (avSeperatorIndex === -1) {
+- attrKey = cookieAV;
+- attrValue = "";
+- } else {
+- attrKey = cookieAV.substr(0, avSeperatorIndex);
+- attrValue = cookieAV.substr(avSeperatorIndex + 1);
+- }
+-
+- attrKey = attrKey.trim().toLowerCase();
+-
+- if (attrValue) {
+- attrValue = attrValue.trim();
+- }
+-
+- switch (attrKey) {
+- case "expires":
+- if (attrValue) {
+- const expires = new Date(attrValue).getTime();
+- if (expires && !isNaN(expires)) {
+- options.expires = expires;
+- }
+- }
+- break;
+-
+- case "max-age":
+- if (attrValue) {
+- const maxAge = parseInt(attrValue, 10);
+- if (!isNaN(maxAge)) {
+- options.maxAge = maxAge;
+- }
+- }
+- break;
+-
+- case "domain":
+- if (attrValue) {
+- const domain = parseURL(attrValue).host;
+- if (domain) {
+- options.domain = domain;
+- }
+- }
+- break;
+-
+- case "path":
+- if (attrValue) {
+- options.path = attrValue.startsWith("/")
+- ? attrValue
+- : "/" + attrValue;
+- }
+- break;
+-
+- case "secure":
+- options.secure = true;
+- break;
+-
+- case "httponly":
+- options.httpOnly = true;
+- break;
+-
+- case "samesite": {
+- const lowerCasedSameSite = attrValue.toLowerCase();
+- switch (lowerCasedSameSite) {
+- case "strict":
+- options.sameSite = "Strict";
+- break;
+- case "lax":
+- options.sameSite = "Lax";
+- break;
+- case "none":
+- options.sameSite = "None";
+- break;
+- default:
+- break;
+- }
+- break;
+- }
+- // unknown attribute
+- default:
+- break;
+- }
+- }
+-
+- return new Cookie(options);
+- }
+-
+- isValid(): boolean {
+- return isValidName(this.name) && isValidValue(this.value);
+- }
+-
+- /**
+- * @param url - the url that we are checking against
+- */
+- canSendTo(url: string | Request | URL) {
+- const urlObj = parseURL(url);
+-
+- if (this.secure && urlObj.protocol !== "https:") {
+- return false;
+- }
+-
+- if (this.sameSite === "None" && !this.secure) return false;
+-
+- if (this.path) {
+- if (
+- this.path === urlObj.pathname // identical
+- ) {
+- return true;
+- }
+- if (
+- urlObj.pathname.startsWith(this.path) &&
+- this.path[this.path.length - 1] === "/" // any sub path after a '/'
+- ) {
+- return true;
+- }
+- if (
+- this.path.length < urlObj.pathname.length &&
+- urlObj.pathname.startsWith(this.path) &&
+- urlObj.pathname[this.path.length] === "/"
+- ) {
+- return true;
+- // this one was a bit tricky to understand for me
+- // quick explain:
+- // imagin two path where A is the cookie path and B and C is the requested paths:
+- // A: /foo
+- // B: /foo/bar --> true
+- // C: /foobar ---> false
+- // Difference with previous if ? very slight difference, A is /foo/ instead of /foo in the example
+- }
+-
+- return false;
+- }
+-
+- if (this.domain) {
+- const host = urlObj.host; // 'host' includes port number, if specified
+- if (isSameDomainOrSubdomain(this.domain, host)) {
+- return true;
+- }
+- }
+-
+- return false;
+- }
+-
+- getCookieString() {
+- return `${this.name || ""}=${this.value || ""}`;
+- }
+-
+- setDomain(url: string | Request | URL) {
+- this.domain = parseURL(url).host;
+- }
+-
+- setPath(url: string | Request | URL) {
+- // https://www.rfc-editor.org/rfc/rfc6265#section-5.1.4
+- const uriPath = parseURL(url).pathname; // step 1
+-
+- if (!uriPath || uriPath[0] !== "/") { // step 2
+- this.path = "/";
+- } else {
+- const rightmostSlashIdx = uriPath.lastIndexOf("/");
+- if (rightmostSlashIdx <= 0) { // step 3
+- this.path = "/";
+- } else { // step 4
+- this.path = uriPath.slice(0, rightmostSlashIdx);
+- }
+- }
+- }
+-
+- setExpires(exp: Date | number) {
+- if (exp instanceof Date) {
+- this.expires = exp.getTime();
+- } else if (typeof exp === "number" && exp >= 0) {
+- this.expires = exp;
+- }
+- }
+-
+- isExpired() {
+- if (this.maxAge !== undefined) {
+- if (Date.now() - this.creationDate >= this.maxAge * 1000) {
+- return true;
+- }
+- }
+- if (this.expires !== undefined) {
+- // now is past beyond the expire
+- if (Date.now() - this.expires >= 0) {
+- return true;
+- }
+- }
+-
+- return false;
+- }
+-
+- toString() {
+- let str = this.getCookieString();
+-
+- if (this.expires && this.expires !== Infinity) {
+- str += "; Expires=" + (new Date(this.expires)).toUTCString();
+- }
+-
+- if (this.maxAge && this.maxAge !== Infinity) {
+- str += `; Max-Age=${this.maxAge}`;
+- }
+-
+- if (this.domain) {
+- str += `; Domain=${this.domain}`;
+- }
+- if (this.path) {
+- str += `; Path=${this.path}`;
+- }
+-
+- if (this.secure) {
+- str += "; Secure";
+- }
+- if (this.httpOnly) {
+- str += "; HttpOnly";
+- }
+- if (this.sameSite) {
+- str += `; SameSite=${this.sameSite}`;
+- }
+-
+- return str;
+- }
+-
+- clone() {
+- return new Cookie(JSON.parse(JSON.stringify(this)));
+- }
+-}
+diff -Nru quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v4.1.4/fetch_wrapper.ts quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v4.1.4/fetch_wrapper.ts
+--- quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v4.1.4/fetch_wrapper.ts 2023-07-22 08:39:00.000000000 +1200
++++ quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v4.1.4/fetch_wrapper.ts 1970-01-01 12:00:00.000000000 +1200
+@@ -1,50 +0,0 @@
+-import { CookieJar } from "./cookie_jar.ts";
+-
+-export type WrapFetchOptions = {
+- /** your own fetch function. defaults to global fetch. This allows wrapping your fetch function multiple times. */
+- fetch?: typeof fetch;
+- /** The cookie jar to use when wrapping fetch. Will create a new one if not provided. */
+- cookieJar?: CookieJar;
+-};
+-
+-type FetchParameters = Parameters<typeof fetch>;
+-
+-export function wrapFetch(options?: WrapFetchOptions): typeof fetch {
+- const { cookieJar = new CookieJar(), fetch = globalThis.fetch } = options ||
+- {};
+-
+- async function wrappedFetch(
+- input: FetchParameters[0],
+- init?: FetchParameters[1],
+- ) {
+- // let fetch handle the error
+- if (!input) {
+- return await fetch(input);
+- }
+- const cookieString = cookieJar.getCookieString(input);
+-
+- let interceptedInit: RequestInit;
+- if (init) {
+- interceptedInit = init;
+- } else if (input instanceof Request) {
+- interceptedInit = input;
+- } else {
+- interceptedInit = {};
+- }
+-
+- if (!(interceptedInit.headers instanceof Headers)) {
+- interceptedInit.headers = new Headers(interceptedInit.headers || {});
+- }
+- interceptedInit.headers.set("cookie", cookieString);
+-
+- const response = await fetch(input, interceptedInit);
+- response.headers.forEach((value, key) => {
+- if (key.toLowerCase() === "set-cookie") {
+- cookieJar.setCookie(value, input);
+- }
+- });
+- return response;
+- }
+-
+- return wrappedFetch;
+-}
+diff -Nru quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v4.1.4/mod.ts quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v4.1.4/mod.ts
+--- quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v4.1.4/mod.ts 2023-07-22 08:39:00.000000000 +1200
++++ quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v4.1.4/mod.ts 1970-01-01 12:00:00.000000000 +1200
+@@ -1,4 +0,0 @@
+-export { Cookie } from "./cookie.ts";
+-export type { CookieOptions } from "./cookie.ts";
+-export { CookieJar } from "./cookie_jar.ts";
+-export * from "./fetch_wrapper.ts";
+diff -Nru quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v5.0.3/cookie_jar.ts quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v5.0.3/cookie_jar.ts
+--- quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v5.0.3/cookie_jar.ts 1970-01-01 12:00:00.000000000 +1200
++++ quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v5.0.3/cookie_jar.ts 2023-02-27 16:31:36.000000000 +1300
+@@ -0,0 +1,264 @@
++import {
++ Cookie,
++ CookieOptions,
++ isSameDomainOrSubdomain,
++ parseURL,
++} from "./cookie.ts";
++
++const strictMatchProps = [
++ "value",
++ "secure",
++ "httpOnly",
++ "maxAge",
++ "expires",
++ "sameSite",
++];
++
++function cookieMatches(
++ options: Cookie | CookieOptions,
++ comparedWith: Cookie,
++ strictMatch = false,
++): boolean {
++ if (
++ options.path !== undefined && !comparedWith.path?.startsWith(options.path)
++ ) {
++ return false;
++ }
++
++ if (options.domain) {
++ if (!isSameDomainOrSubdomain(options.domain, comparedWith.domain)) {
++ return false;
++ }
++ }
++
++ if (
++ options.name !== undefined &&
++ options.name !== comparedWith.name
++ ) {
++ return false;
++ }
++
++ if (
++ strictMatch &&
++ strictMatchProps.some((propKey) =>
++ // deno-lint-ignore ban-ts-comment
++ // @ts-ignore
++ options[propKey] !== undefined &&
++ // deno-lint-ignore ban-ts-comment
++ // @ts-ignore
++ options[propKey] !== comparedWith[propKey]
++ )
++ ) {
++ return false;
++ }
++
++ return true;
++}
++
++// cookie compare from tough-cookie
++const MAX_TIME = 2147483647000; // 31-bit max
++/**
++ * Cookies with longer paths are listed before cookies with
++ * shorter paths.
++ *
++ * Among cookies that have equal-length path fields, cookies with
++ * earlier creation-times are listed before cookies with later
++ * creation-times."
++ */
++function cookieCompare(a: Cookie, b: Cookie) {
++ let cmp = 0;
++
++ // descending for length: b CMP a
++ const aPathLen = a.path?.length || 0;
++ const bPathLen = b.path?.length || 0;
++ cmp = bPathLen - aPathLen;
++ if (cmp !== 0) {
++ return cmp;
++ }
++
++ // ascending for time: a CMP b
++ const aTime = a.creationDate || MAX_TIME;
++ const bTime = b.creationDate || MAX_TIME;
++ cmp = aTime - bTime;
++ if (cmp !== 0) {
++ return cmp;
++ }
++
++ // tie breaker
++ cmp = a.creationIndex - b.creationIndex;
++
++ return cmp;
++}
++
++export class CookieJar {
++ cookies = Array<Cookie>();
++
++ /**
++ * @param cookies - the cookies array to initialize with
++ */
++ constructor(cookies?: Array<Cookie> | Array<CookieOptions>) {
++ this.replaceCookies(cookies);
++ }
++
++ /**
++ * Sets or replaces a cookie inside the jar.
++ * Only sets new cookies if cookie is valid and not expired.
++ * Validation and expiration checks are not run when replacing a cookie.
++ * @param url - the url that this cookie from received from. mainly used by the fetch wrapper.
++ * will automatically set domain and path if provided and it was not found inside Cookie/cookiestring.
++ */
++ setCookie(cookie: Cookie | string, url?: string | Request | URL) {
++ let cookieObj;
++ if (typeof cookie === "string") {
++ cookieObj = Cookie.from(cookie);
++ } else {
++ cookieObj = cookie;
++ }
++ if (url) {
++ if (!cookieObj.domain) {
++ cookieObj.setDomain(url);
++ }
++ if (!cookieObj.path) {
++ cookieObj.setPath(url);
++ }
++ }
++
++ if (!cookieObj.isValid()) {
++ return;
++ }
++
++ const foundCookie = this.getCookie(cookieObj);
++ if (foundCookie) {
++ const indexOfCookie = this.cookies.indexOf(foundCookie);
++ if (!cookieObj.isExpired()) {
++ this.cookies.splice(indexOfCookie, 1, cookieObj);
++ } else {
++ this.cookies.splice(indexOfCookie, 1);
++ }
++ } else if (!cookieObj.isExpired()) {
++ this.cookies.push(cookieObj);
++ }
++
++ // sort by creation date, so when searching, we get the latest created cookies.
++ this.cookies.sort(cookieCompare);
++ }
++
++ /**
++ * Gets the first cooking matching the defined properties of a given Cookie or CookieOptions.
++ * returns undefined if not found or expired. `creationDate` prop is not checked.
++ * Also removes the cookie and returns undefined if cookie is expired.
++ */
++ getCookie(options: Cookie | CookieOptions): Cookie | undefined {
++ const strictMatch = typeof (options as Cookie).isValid !== "function";
++ for (const [index, cookie] of this.cookies.entries()) {
++ if (cookieMatches(options, cookie, strictMatch)) {
++ if (!cookie.isExpired()) {
++ return cookie;
++ } else {
++ this.cookies.splice(index, 1);
++ return undefined;
++ }
++ }
++ }
++ }
++
++ /**
++ * Returns cookies that match the options excluding expired ones, also removes expired cookies before returning.
++ * @param options - the options to filter cookies with, and if not provided, returnes all cookies.
++ * if no cookie is found with given options, an empty array is returned.
++ */
++ getCookies(options?: CookieOptions | Cookie) {
++ if (options) {
++ const matchedCookies: Cookie[] = [];
++ const removeCookies: Cookie[] = [];
++ for (const cookie of this.cookies) {
++ if (cookieMatches(options, cookie)) {
++ if (!cookie.isExpired()) {
++ matchedCookies.push(cookie);
++ } else {
++ removeCookies.push(cookie);
++ }
++ }
++ }
++ if (removeCookies.length) {
++ this.cookies = this.cookies.filter((cookie) =>
++ !removeCookies.includes(cookie)
++ );
++ }
++ return matchedCookies;
++ } else {
++ return this.cookies;
++ }
++ }
++
++ /**
++ * Converts the cookies to a string that can be used in a request.
++ * @param url - the url to get the cookies for. if provided, will only return cookies that match the domain and path of the url.
++ * @returns string of all cookies that match the url, in the from of `<cookie-name>=<cookie-value>` seperated by `; `
++ */
++ getCookieString(url: string | Request | URL) {
++ const searchCookie = new Cookie();
++ searchCookie.setDomain(url);
++ const cookiesToSend = this.getCookies(searchCookie)
++ .filter((cookie) => {
++ return cookie.canSendTo(parseURL(url));
++ })
++ .map((c) => c.getCookieString())
++ .join("; ");
++ return cookiesToSend;
++ }
++
++ toJSON() {
++ return this.cookies;
++ }
++
++ /**
++ * Removes first cookie that matches the given option.
++ *
++ * Returns the deleted cookie if found or undefined otherwise.
++ */
++ removeCookie(options: CookieOptions | Cookie): Cookie | undefined {
++ for (const [index, cookie] of this.cookies.entries()) {
++ if (cookieMatches(options, cookie)) {
++ return this.cookies.splice(index, 1)[0];
++ }
++ }
++ }
++
++ /**
++ * Removes all cookies that matches the given option.
++ * If options is not given, all cookies will be deleted.
++ *
++ * Returns the deleted cookies if found or undefined otherwise.
++ */
++ removeCookies(options?: CookieOptions | Cookie): Array<Cookie> | undefined {
++ if (options) {
++ const deletedCookies: Cookie[] = [];
++ this.cookies = this.cookies.filter((cookie) => {
++ if (cookieMatches(options, cookie)) {
++ deletedCookies.push(cookie);
++ return false;
++ }
++ return true;
++ });
++ return deletedCookies.length ? deletedCookies : undefined;
++ } else {
++ this.cookies = [];
++ }
++ }
++
++ replaceCookies(cookies?: Array<Cookie> | Array<CookieOptions>) {
++ if (cookies?.length) {
++ if (typeof (cookies[0] as Cookie).isValid === "function") {
++ this.cookies = cookies as Array<Cookie>;
++ } else {
++ this.cookies = [];
++ for (const option of cookies) {
++ this.cookies.push(new Cookie(option));
++ }
++ }
++ } else {
++ this.cookies = [];
++ }
++ }
++}
+diff -Nru quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v5.0.3/cookie.ts quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v5.0.3/cookie.ts
+--- quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v5.0.3/cookie.ts 1970-01-01 12:00:00.000000000 +1200
++++ quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v5.0.3/cookie.ts 2023-02-27 16:31:36.000000000 +1300
+@@ -0,0 +1,452 @@
++// import { } from "./deps.ts";
++
++// deno-lint-ignore no-control-regex
++const CONTROL_CHARS = /[\x00-\x1F\x7F]/;
++
++// with help from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie and rfc6265
++const COOKIE_NAME_BLOCKED = /[()<>@,;:\\"/[\]?={}]/;
++
++// cookie octet should not have control characters, Whitespace, double quotes, comma, semicolon, and backslash
++const COOKIE_OCTET_BLOCKED = /[\s",;\\]/;
++const COOKIE_OCTET = /^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]+$/;
++
++const TERMINATORS = ["\n", "\r", "\0"];
++
++/**
++ * does not make a difference which one is domainA or domainB
++ *
++ * according to https://stackoverflow.com/a/30676300/3542461
++ */
++export function isSameDomainOrSubdomain(domainA?: string, domainB?: string) {
++ if (!domainA || !domainB) {
++ return false;
++ }
++
++ let longerDomain;
++ let shorterDomain;
++ if (domainB.length > domainA.length) {
++ longerDomain = domainB;
++ shorterDomain = domainA;
++ } else {
++ longerDomain = domainA;
++ shorterDomain = domainB;
++ }
++
++ // check if it's a subdomain or only partially matched
++ const indexOfDomain = longerDomain.indexOf(shorterDomain);
++ if (indexOfDomain === -1) {
++ return false;
++ } else if (indexOfDomain > 0) {
++ // if the character behind the part is not a dot, its not a subdomain
++ if (longerDomain.charAt(indexOfDomain - 1) !== ".") {
++ return false;
++ }
++ }
++ // indexOfDomain === 0 is valid
++
++ return true;
++}
++
++// from tough-cookie
++function trimTerminator(str: string) {
++ if (str === undefined || str === "") return str;
++ for (let t = 0; t < TERMINATORS.length; t++) {
++ const terminatorIdx = str.indexOf(TERMINATORS[t]);
++ if (terminatorIdx !== -1) {
++ str = str.substr(0, terminatorIdx);
++ }
++ }
++
++ return str;
++}
++
++function isValidName(name: string | undefined) {
++ if (!name) {
++ return false;
++ }
++ if (CONTROL_CHARS.test(name) || COOKIE_NAME_BLOCKED.test(name)) {
++ return false;
++ }
++ return true;
++}
++
++function trimWrappingDoubleQuotes(val: string) {
++ // the value can be wrapped in double quotes, but can't contain double quotes within the value
++ if (val.length >= 2 && val.at(0) === '"' && val.at(-1) === '"') {
++ return val.slice(1, -1);
++ }
++ return val;
++}
++
++function isValidValue(val: string | undefined) {
++ if (val === "") {
++ return true;
++ }
++ if (!val) {
++ return false;
++ }
++ if (
++ CONTROL_CHARS.test(val) ||
++ COOKIE_OCTET_BLOCKED.test(val) ||
++ !COOKIE_OCTET.test(val)
++ ) {
++ return false;
++ }
++
++ return true;
++}
++
++export function parseURL(input: string | Request | URL) {
++ let copyUrl: string;
++ if (input instanceof Request) {
++ copyUrl = input.url;
++ } else if (input instanceof URL) {
++ copyUrl = input.toString();
++ } else {
++ copyUrl = input;
++ }
++ // we *need* to replace the leading dot to simplify usage and expectations
++ copyUrl = copyUrl.replace(/^\./, "");
++ if (!copyUrl.includes("://")) {
++ // the protocol does not matter, but we default to insecure for use inside canSendTo
++ copyUrl = "http://" + copyUrl;
++ }
++ return new URL(copyUrl);
++}
++
++export type CookieOptions = {
++ name?: string;
++ value?: string;
++ path?: string;
++ domain?: string;
++ /** in milliseconds */
++ expires?: number;
++ /** in seconds */
++ maxAge?: number;
++ secure?: boolean;
++ httpOnly?: boolean;
++ sameSite?: "Lax" | "Strict" | "None";
++ /** used for checking against maxAge */
++ creationDate?: number;
++};
++
++export class Cookie {
++ // important
++ name: string | undefined;
++ value: string | undefined;
++ path: string | undefined;
++ domain: string | undefined;
++ // expire
++ /** in milliseconds */
++ expires: number | undefined;
++ /** in seconds */
++ maxAge: number | undefined;
++ // other
++ secure: boolean | undefined;
++ httpOnly: boolean | undefined;
++ sameSite: "Lax" | "Strict" | "None" | undefined;
++ creationDate = Date.now();
++ // deno-lint-ignore ban-ts-comment
++ // @ts-ignore
++ creationIndex: number;
++
++ static cookiesCreated = 0;
++
++ constructor(options?: CookieOptions) {
++ if (options) {
++ this.name = options.name;
++ this.value = options.value;
++ this.path = options.path;
++ this.domain = options.domain;
++ this.expires = options.expires;
++ this.maxAge = options.maxAge;
++ this.secure = options.secure;
++ this.httpOnly = options.httpOnly;
++ this.sameSite = options.sameSite;
++
++ if (options.creationDate) {
++ this.creationDate = options.creationDate;
++ }
++ }
++
++ // used to break creation ties in cookieCompare():
++ Object.defineProperty(this, "creationIndex", {
++ configurable: false,
++ enumerable: false, // important for assertStrictEquals checks
++ writable: true,
++ value: ++Cookie.cookiesCreated,
++ });
++ }
++
++ static from(cookieStr: string) {
++ const options = {
++ name: undefined,
++ value: undefined,
++ path: undefined,
++ domain: undefined,
++ expires: undefined,
++ maxAge: undefined,
++ secure: undefined,
++ httpOnly: undefined,
++ sameSite: undefined,
++ creationDate: Date.now(),
++ } as CookieOptions;
++
++ const unparsed = cookieStr.slice().trim(); // copy
++ const attrAndValueList = unparsed.split(";");
++
++ // first split is the key value pair,
++ // if theres no semicolon in the string, still the first element in array is key value pair
++ const keyValuePairString = trimTerminator(attrAndValueList.shift() || "")
++ .trim();
++ const keyValuePairEqualsIndex = keyValuePairString.indexOf("=");
++ if (keyValuePairEqualsIndex < 0) {
++ return new Cookie();
++ }
++ const name = keyValuePairString.slice(0, keyValuePairEqualsIndex);
++ const value = trimWrappingDoubleQuotes(
++ keyValuePairString.slice(keyValuePairEqualsIndex + 1),
++ );
++
++ if (!(isValidName(name) && isValidValue(value))) {
++ return new Cookie();
++ }
++ options.name = name;
++ options.value = value;
++
++ // now get attributes
++ while (attrAndValueList.length) {
++ const cookieAV = attrAndValueList.shift()?.trim();
++ if (!cookieAV) {
++ // invalid attribute length
++ continue;
++ }
++
++ const avSeperatorIndex = cookieAV.indexOf("=");
++ let attrKey, attrValue;
++
++ if (avSeperatorIndex === -1) {
++ attrKey = cookieAV;
++ attrValue = "";
++ } else {
++ attrKey = cookieAV.substr(0, avSeperatorIndex);
++ attrValue = cookieAV.substr(avSeperatorIndex + 1);
++ }
++
++ attrKey = attrKey.trim().toLowerCase();
++
++ if (attrValue) {
++ attrValue = attrValue.trim();
++ }
++
++ switch (attrKey) {
++ case "expires":
++ if (attrValue) {
++ const expires = new Date(attrValue).getTime();
++ if (expires && !isNaN(expires)) {
++ options.expires = expires;
++ }
++ }
++ break;
++
++ case "max-age":
++ if (attrValue) {
++ const maxAge = parseInt(attrValue, 10);
++ if (!isNaN(maxAge)) {
++ options.maxAge = maxAge;
++ }
++ }
++ break;
++
++ case "domain":
++ if (attrValue) {
++ const domain = parseURL(attrValue).hostname;
++ if (domain) {
++ options.domain = domain;
++ }
++ }
++ break;
++
++ case "path":
++ if (attrValue) {
++ options.path = attrValue.startsWith("/")
++ ? attrValue
++ : "/" + attrValue;
++ }
++ break;
++
++ case "secure":
++ options.secure = true;
++ break;
++
++ case "httponly":
++ options.httpOnly = true;
++ break;
++
++ case "samesite": {
++ const lowerCasedSameSite = attrValue.toLowerCase();
++ switch (lowerCasedSameSite) {
++ case "strict":
++ options.sameSite = "Strict";
++ break;
++ case "lax":
++ options.sameSite = "Lax";
++ break;
++ case "none":
++ options.sameSite = "None";
++ break;
++ default:
++ break;
++ }
++ break;
++ }
++ // unknown attribute
++ default:
++ break;
++ }
++ }
++
++ return new Cookie(options);
++ }
++
++ isValid(): boolean {
++ return isValidName(this.name) && isValidValue(this.value);
++ }
++
++ /**
++ * @param url - the url that we are checking against
++ */
++ canSendTo(url: string | Request | URL) {
++ const urlObj = parseURL(url);
++
++ if (this.secure && urlObj.protocol !== "https:") {
++ return false;
++ }
++
++ if (this.sameSite === "None" && !this.secure) return false;
++
++ if (this.path) {
++ if (
++ this.path === urlObj.pathname // identical
++ ) {
++ return true;
++ }
++ if (
++ urlObj.pathname.startsWith(this.path) &&
++ this.path[this.path.length - 1] === "/" // any sub path after a '/'
++ ) {
++ return true;
++ }
++ if (
++ this.path.length < urlObj.pathname.length &&
++ urlObj.pathname.startsWith(this.path) &&
++ urlObj.pathname[this.path.length] === "/"
++ ) {
++ return true;
++ // this one was a bit tricky to understand for me
++ // quick explain:
++ // imagin two path where A is the cookie path and B and C is the requested paths:
++ // A: /foo
++ // B: /foo/bar --> true
++ // C: /foobar ---> false
++ // Difference with previous if ? very slight difference, A is /foo/ instead of /foo in the example
++ }
++
++ return false;
++ }
++
++ if (this.domain) {
++ // according to rfc 6265 8.5. Weak Confidentiality,
++ // port should not matter, hence the usage of 'hostname' over 'host'
++ const hostname = urlObj.hostname; // 'host' includes port number, if specified, hostname does not
++ if (isSameDomainOrSubdomain(this.domain, hostname)) {
++ return true;
++ }
++ }
++
++ return false;
++ }
++
++ getCookieString() {
++ return `${this.name || ""}=${this.value || ""}`;
++ }
++
++ setDomain(url: string | Request | URL) {
++ this.domain = parseURL(url).hostname;
++ }
++
++ setPath(url: string | Request | URL) {
++ // https://www.rfc-editor.org/rfc/rfc6265#section-5.1.4
++ const uriPath = parseURL(url).pathname; // step 1
++
++ if (!uriPath || uriPath[0] !== "/") { // step 2
++ this.path = "/";
++ } else {
++ const rightmostSlashIdx = uriPath.lastIndexOf("/");
++ if (rightmostSlashIdx <= 0) { // step 3
++ this.path = "/";
++ } else { // step 4
++ this.path = uriPath.slice(0, rightmostSlashIdx);
++ }
++ }
++ }
++
++ setExpires(exp: Date | number) {
++ if (exp instanceof Date) {
++ this.expires = exp.getTime();
++ } else if (typeof exp === "number" && exp >= 0) {
++ this.expires = exp;
++ }
++ }
++
++ isExpired() {
++ if (this.maxAge !== undefined) {
++ if (Date.now() - this.creationDate >= this.maxAge * 1000) {
++ return true;
++ }
++ }
++ if (this.expires !== undefined) {
++ // now is past beyond the expire
++ if (Date.now() - this.expires >= 0) {
++ return true;
++ }
++ }
++
++ return false;
++ }
++
++ toString() {
++ let str = this.getCookieString();
++
++ if (this.expires && this.expires !== Infinity) {
++ str += "; Expires=" + (new Date(this.expires)).toUTCString();
++ }
++
++ if (this.maxAge && this.maxAge !== Infinity) {
++ str += `; Max-Age=${this.maxAge}`;
++ }
++
++ if (this.domain) {
++ str += `; Domain=${this.domain}`;
++ }
++ if (this.path) {
++ str += `; Path=${this.path}`;
++ }
++
++ if (this.secure) {
++ str += "; Secure";
++ }
++ if (this.httpOnly) {
++ str += "; HttpOnly";
++ }
++ if (this.sameSite) {
++ str += `; SameSite=${this.sameSite}`;
++ }
++
++ return str;
++ }
++
++ clone() {
++ return new Cookie(JSON.parse(JSON.stringify(this)));
++ }
++}
+diff -Nru quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v5.0.3/fetch_wrapper.ts quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v5.0.3/fetch_wrapper.ts
+--- quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v5.0.3/fetch_wrapper.ts 1970-01-01 12:00:00.000000000 +1200
++++ quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v5.0.3/fetch_wrapper.ts 2023-02-27 16:31:36.000000000 +1300
+@@ -0,0 +1,145 @@
++import { CookieJar } from "./cookie_jar.ts";
++
++// Max 20 redirects is fetch default setting
++const MAX_REDIRECT = 20;
++
++export type WrapFetchOptions = {
++ /** your own fetch function. defaults to global fetch. This allows wrapping your fetch function multiple times. */
++ fetch?: typeof fetch;
++ /** The cookie jar to use when wrapping fetch. Will create a new one if not provided. */
++ cookieJar?: CookieJar;
++};
++
++interface ExtendedRequestInit extends RequestInit {
++ redirectCount?: number;
++}
++
++const redirectStatus = new Set([301, 302, 303, 307, 308]);
++
++function isRedirect(status: number): boolean {
++ return redirectStatus.has(status);
++}
++
++// Credit <https://github.com/node-fetch/node-fetch/blob/5e78af3ba7555fa1e466e804b2e51c5b687ac1a2/src/utils/is.js#L68>.
++function isDomainOrSubdomain(destination: string, original: string): boolean {
++ const orig = new URL(original).hostname;
++ const dest = new URL(destination).hostname;
++
++ return orig === dest || orig.endsWith(`.${dest}`);
++}
++
++export function wrapFetch(options?: WrapFetchOptions): typeof fetch {
++ const { cookieJar = new CookieJar(), fetch = globalThis.fetch } = options ||
++ {};
++
++ async function wrappedFetch(
++ input: RequestInfo | URL,
++ init?: ExtendedRequestInit,
++ ): Promise<Response> {
++ // let fetch handle the error
++ if (!input) {
++ return await fetch(input);
++ }
++ const cookieString = cookieJar.getCookieString(input);
++
++ let originalRedirectOption: ExtendedRequestInit["redirect"];
++ const originalRequestUrl: string = (input as Request).url ||
++ input.toString();
++
++ if (input instanceof Request) {
++ originalRedirectOption = input.redirect;
++ }
++ if (init?.redirect) {
++ originalRedirectOption = init?.redirect;
++ }
++
++ const interceptedInit: ExtendedRequestInit = {
++ ...init,
++ redirect: "manual",
++ };
++
++ const reqHeaders = new Headers((input as Request).headers || {});
++
++ if (init?.headers) {
++ new Headers(init.headers).forEach((value, key) => {
++ reqHeaders.set(key, value);
++ });
++ }
++
++ reqHeaders.set("cookie", cookieString);
++ reqHeaders.delete("cookie2"); // Remove cookie2 if it exists, It's deprecated
++
++ interceptedInit.headers = reqHeaders;
++
++ const response = await fetch(input, interceptedInit as RequestInit);
++
++ response.headers.forEach((value, key) => {
++ if (key.toLowerCase() === "set-cookie") {
++ cookieJar.setCookie(value, response.url);
++ }
++ });
++
++ const redirectCount = interceptedInit.redirectCount ?? 0;
++ const redirectUrl = response.headers.has("location")
++ ? new URL(
++ response.headers.get("location")!.toString(),
++ originalRequestUrl,
++ ).toString()
++ : undefined;
++
++ // Do this check here to allow tail recursion of redirect.
++ if (redirectCount > 0) {
++ Object.defineProperty(response, "redirected", { value: true });
++ }
++
++ if (
++ // Return if response is not redirect
++ !isRedirect(response.status) ||
++ // or location is not set
++ !redirectUrl ||
++ // or if it's the first request and request.redirect is set to 'manual'
++ (redirectCount === 0 && originalRedirectOption === "manual")
++ ) {
++ return response;
++ }
++
++ if (originalRedirectOption === "error") {
++ await response.body?.cancel();
++ throw new TypeError(
++ `URI requested responded with a redirect and redirect mode is set to error: ${response.url}`,
++ );
++ }
++
++ // If maximum redirects are reached throw error
++ if (redirectCount >= MAX_REDIRECT) {
++ await response.body?.cancel();
++ throw new TypeError(
++ `Reached maximum redirect of ${MAX_REDIRECT} for URL: ${response.url}`,
++ );
++ }
++
++ await response.body?.cancel();
++
++ interceptedInit.redirectCount = redirectCount + 1;
++
++ const filteredHeaders = new Headers(interceptedInit.headers);
++
++ // Do not forward sensitive headers to third-party domains.
++ if (!isDomainOrSubdomain(originalRequestUrl, redirectUrl)) {
++ for (const name of ["authorization", "www-authenticate"]) { // cookie headers are handled differently
++ filteredHeaders.delete(name);
++ }
++ }
++
++ if (interceptedInit.method === "POST") {
++ filteredHeaders.delete("content-length");
++ interceptedInit.method = "GET";
++ interceptedInit.body = undefined;
++ }
++ interceptedInit.headers = filteredHeaders;
++
++ return await wrappedFetch(redirectUrl, interceptedInit as RequestInit);
++ }
++
++ return wrappedFetch;
++}
+diff -Nru quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v5.0.3/mod.ts quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v5.0.3/mod.ts
+--- quarto-cli-1.4.250.original/src/vendor/deno.land/x/another_cookiejar@v5.0.3/mod.ts 1970-01-01 12:00:00.000000000 +1200
++++ quarto-cli-1.4.250/src/vendor/deno.land/x/another_cookiejar@v5.0.3/mod.ts 2023-02-27 16:31:36.000000000 +1300
+@@ -0,0 +1,4 @@
++export { Cookie } from "./cookie.ts";
++export type { CookieOptions } from "./cookie.ts";
++export { CookieJar } from "./cookie_jar.ts";
++export * from "./fetch_wrapper.ts";
+diff -Nru quarto-cli-1.4.250.original/src/vendor/import_map.json quarto-cli-1.4.250/src/vendor/import_map.json
+--- quarto-cli-1.4.250.original/src/vendor/import_map.json 2023-07-22 08:39:00.000000000 +1200
++++ quarto-cli-1.4.250/src/vendor/import_map.json 2023-07-22 10:18:46.244042638 +1200
+@@ -81,7 +81,7 @@
+ "crypto/mod.ts": "./deno.land/std@0.185.0/crypto/mod.ts",
+ "encoding/hex.ts": "./deno.land/std@0.185.0/encoding/hex.ts",
+ "cliffy/prompt/secret.ts": "./deno.land/x/cliffy@v0.25.4/prompt/secret.ts",
+- "another_cookiejar/mod.ts": "./deno.land/x/another_cookiejar@v4.1.4/mod.ts",
++ "another_cookiejar/mod.ts": "./deno.land/x/another_cookiejar@v5.0.3/mod.ts",
+ "binary-search-bounds": "./cdn.skypack.dev/binary-search-bounds@2.0.5.js",
+ "testing/asserts.ts": "./deno.land/std@0.185.0/testing/asserts.ts",
+ "https://deno.land/std@0.161.0/fmt/colors.ts": "./deno.land/std@0.185.0/fmt/colors.ts",
diff --git a/001_vendor_patch_2.diff b/001_vendor_patch_2.diff
new file mode 100644
index 000000000000..38af763c0241
--- /dev/null
+++ b/001_vendor_patch_2.diff
@@ -0,0 +1,33 @@
+diff -Nu quarto-cli-1.4.250.original/src/dev_import_map.json quarto-cli-1.4.250/src/dev_import_map.json
+--- quarto-cli-1.4.250.original/src/dev_import_map.json 2023-07-22 08:39:00.000000000 +1200
++++ quarto-cli-1.4.250/src/dev_import_map.json 2023-07-22 10:18:23.820831240 +1200
+@@ -30,7 +30,7 @@
+ "deno_dom/": "./vendor/deno.land/x/deno_dom@v0.1.35-alpha/",
+ "xmlp/": "./vendor/deno.land/x/xmlp@v0.2.8/",
+ "xml/": "./vendor/deno.land/x/xml@2.1.1/",
+- "another_cookiejar/": "./vendor/deno.land/x/another_cookiejar@v4.1.4/",
++ "another_cookiejar/": "./vendor/deno.land/x/another_cookiejar@v5.0.3/",
+ "semver/": "./vendor/deno.land/x/semver@v1.4.0/",
+ "media_types/": "./vendor/deno.land/x/media_types@v2.10.1/",
+ "dayjs/": "./vendor/cdn.skypack.dev/dayjs@1.8.21/",
+@@ -125,7 +125,7 @@
+ "crypto/mod.ts": "./vendor/deno.land/std@0.185.0/crypto/mod.ts",
+ "encoding/hex.ts": "./vendor/deno.land/std@0.185.0/encoding/hex.ts",
+ "cliffy/prompt/secret.ts": "./vendor/deno.land/x/cliffy@v0.25.4/prompt/secret.ts",
+- "another_cookiejar/mod.ts": "./vendor/deno.land/x/another_cookiejar@v4.1.4/mod.ts",
++ "another_cookiejar/mod.ts": "./vendor/deno.land/x/another_cookiejar@v5.0.3/mod.ts",
+ "testing/asserts.ts": "./vendor/deno.land/std@0.185.0/testing/asserts.ts",
+ "https://deno.land/std@0.161.0/fmt/colors.ts": "./vendor/deno.land/std@0.185.0/fmt/colors.ts",
+ "https://deno.land/std@0.161.0/encoding/base64.ts": "./vendor/deno.land/std@0.185.0/encoding/base64.ts",
+diff -Nu quarto-cli-1.4.250.original/src/import_map.json quarto-cli-1.4.250/src/import_map.json
+--- quarto-cli-1.4.250.original/src/import_map.json 2023-07-22 08:39:00.000000000 +1200
++++ quarto-cli-1.4.250/src/import_map.json 2023-07-22 10:18:34.027442398 +1200
+@@ -30,7 +30,7 @@
+ "deno_dom/": "https://deno.land/x/deno_dom@v0.1.35-alpha/",
+ "xmlp/": "https://deno.land/x/xmlp@v0.2.8/",
+ "xml/": "https://deno.land/x/xml@2.1.1/",
+- "another_cookiejar/": "https://deno.land/x/another_cookiejar@v4.1.4/",
++ "another_cookiejar/": "https://deno.land/x/another_cookiejar@v5.0.3/",
+ "semver/": "https://deno.land/x/semver@v1.4.0/",
+ "media_types/": "https://deno.land/x/media_types@v2.10.1/",
+ "dayjs/": "https://cdn.skypack.dev/dayjs@1.8.21/",
diff --git a/002_multi_def_patch_1.diff b/002_multi_def_patch_1.diff
new file mode 100644
index 000000000000..fa136efee612
--- /dev/null
+++ b/002_multi_def_patch_1.diff
@@ -0,0 +1,11 @@
+diff -Nru quarto-cli-1.4.250.original/src/format/formats-shared.ts quarto-cli-1.4.250/src/format/formats-shared.ts
+--- quarto-cli-1.4.250.original/src/format/formats-shared.ts 2023-07-22 08:39:00.000000000 +1200
++++ quarto-cli-1.4.250/src/format/formats-shared.ts 2023-07-22 10:15:16.808512080 +1200
+@@ -242,7 +242,6 @@
+ [kLatexAutoMk]: true,
+ [kLatexAutoInstall]: true,
+ [kLatexClean]: true,
+- [kLatexMaxRuns]: 1,
+ [kLatexMaxRuns]: 10,
+ [kLatexMakeIndex]: "makeindex",
+ [kLatexMakeIndexOpts]: [],
diff --git a/002_multi_def_patch_2.diff b/002_multi_def_patch_2.diff
new file mode 100644
index 000000000000..e03a08ab6a33
--- /dev/null
+++ b/002_multi_def_patch_2.diff
@@ -0,0 +1,11 @@
+diff -Nru quarto-cli-1.4.250.original/src/render/notebook/notebook-contributor-jats.ts quarto-cli-1.4.250/src/render/notebook/notebook-contributor-jats.ts
+--- quarto-cli-1.4.250.original/src/render/notebook/notebook-contributor-jats.ts 2023-07-22 08:39:00.000000000 +1200
++++ quarto-cli-1.4.250/src/render/notebook/notebook-contributor-jats.ts 2023-07-22 10:15:31.408433063 +1200
+@@ -102,7 +102,6 @@
+ [kOutputFile]: outputFile(nbPath),
+ [kTemplate]: subarticleTemplatePath,
+ [kNotebookPreserveCells]: true,
+- [kNotebookPreserveCells]: true,
+ },
+ quiet: false,
+ },
diff --git a/PKGBUILD b/PKGBUILD
index 5888321e7ba4..35facc34a532 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,18 +1,15 @@
# Maintainer: Aleksandr Beliaev <trap000d at gmail dot com>
pkgname=quarto-cli-git
-pkgver=1.4.96.r1.gf23b0ad34
+pkgver=1.4.274.r2.gd9c08cbc9
pkgrel=1
_pkgbasename=quarto-cli
_denodomver="0.1.35-alpha-artifacts"
_deno_arch="deno-x86_64-unknown-linux-gnu"
-_denocliffyver="0.25.7"
-_denostdver="0.170.0"
-
pkgdesc="Quarto is an open-source scientific and technical publishing system built on [Pandoc](https://pandoc.org). This package tracks main git branch of Quarto."
arch=('x86_64' 'i686')
-depends=('nodejs' 'deno' 'dart-sass' 'esbuild' 'pandoc' 'lua-lpeg')
+depends=('nodejs' 'deno' 'dart-sass' 'esbuild' 'pandoc' 'lua-lpeg' 'typst')
makedepends=('git' 'npm' 'rust')
url="https://quarto.org/"
license=('MIT')
@@ -22,20 +19,39 @@ options=(!strip)
source=("git+https://github.com/quarto-dev/quarto-cli.git"
"https://github.com/b-fuze/deno-dom/archive/refs/tags/v${_denodomver}.tar.gz"
- "https://github.com/c4spar/deno-cliffy/archive/refs/tags/v${_denocliffyver}.tar.gz"
- "https://github.com/denoland/deno_std/archive/refs/tags/${_denostdver}.tar.gz"
+ "https://github.com/c4spar/deno-cliffy/archive/refs/tags/v0.25.7.tar.gz"
+ "https://github.com/denoland/deno_std/archive/refs/tags/0.170.0.tar.gz"
+ "001_vendor_patch_1.diff"
+ "001_vendor_patch_2.diff"
+ "002_multi_def_patch_1.diff"
+ "002_multi_def_patch_2.diff"
)
sha256sums=('SKIP'
'14fb042a6912041b9fda91fd643cf278764d075bc9539aa1e107475915cd896c'
'519709be1dfcf4743930b7f21a513d8fbf3663380020eac8ba629081395f6cc0'
- '369bc68b848532bedcb786a8fce5e52000624b9262f05ceeeb16bc851b6cf752')
+ '369bc68b848532bedcb786a8fce5e52000624b9262f05ceeeb16bc851b6cf752'
+ '937a39f116c4310c4989cf71b9e174b6dc7bfdd84c6632e5dd0b47508cffef86'
+ '144101b799267869395ba2fe85ab8549be277b18af9545c106675f620e73a85b'
+ '6c1adcf6a21ab6a2949eee9770fe19ef453758dc2e1d3f7a071f07c66d5c92b2'
+ '1ee399808579aa05f38b9c27dfd23e9102f38fffb437233d360b0c076118312f')
pkgver() {
cd ${_pkgbasename}
git describe --tags | sed 's/^v//' | sed 's/\([^-v]*-g\)/r\1/;s/-/./g'
}
+prepare() {
+ cd "${srcdir}/${_pkgbasename}"
+ msg "Patching cookiejar..."
+ patch -p1 < ../001_vendor_patch_1.diff
+ patch -p1 < ../001_vendor_patch_2.diff
+ msg "Patching multi definitions..."
+ patch -p1 < ../002_multi_def_patch_1.diff
+ patch -p1 < ../002_multi_def_patch_2.diff
+
+}
+
build() {
cd "${srcdir}/${_pkgbasename}"
source configuration
@@ -46,35 +62,39 @@ build() {
if [ -z "$QUARTO_DENO" ]; then
export QUARTO_DENO=$SCRIPT_PATH/../dist/bin/tools/deno
fi
+ # keep deno cache directory out of default $home/.cache/deno
+ export DENO_DIR="${srcdir}/${_pkgbasename}/package/cache"
- #mkdir -p package/dist/bin/tools/${_deno_arch}/{deno_dom,dart-sass}
- mkdir -p package/dist/bin/tools/${_deno_arch}
- mkdir -p package/dist/bin/tools/dart-sass
- mkdir -p package/dist/bin/tools/deno_dom
+ mkdir -p package/dist/bin/tools/${arch}/dart-sass
+ mkdir -p package/dist/bin/tools/${arch}/deno_dom
cp /usr/bin/deno package/dist/bin/tools
- ln -sfT /usr/bin/pandoc package/dist/bin/tools/pandoc
- ln -sfT /usr/bin/sass package/dist/bin/tools/dart-sass/sass
- ln -sfT /usr/bin/esbuild package/dist/bin/tools/esbuild
+ ln -sfT /usr/bin/pandoc package/dist/bin/tools/${arch}/pandoc
+ ln -sfT /usr/bin/sass package/dist/bin/tools/${arch}/dart-sass/sass
+ ln -sfT /usr/bin/esbuild package/dist/bin/tools/${arch}/esbuild
msg "Building Deno Stdlib..."
cd "${srcdir}/deno-dom-${_denodomver}"
cargo build --release
- cd "${srcdir}/${_pkgbasename}/package/src"
+ cd "${srcdir}/${_pkgbasename}"
+ # unsure if it's needed at all
+ # package/dist/bin/tools/deno run --allow-all package/src/common/create-deno-config.ts > deno.jsonc
+ cd package/src
+ #../dist/bin/tools/deno run --unstable --allow-env --allow-read --allow-write --allow-run --allow-net --allow-ffi --importmap=../../src/dev_import_map.json bld.ts configure --log-level info
../dist/bin/tools/deno run --unstable --allow-env --allow-read --allow-write --allow-run --allow-net --allow-ffi --importmap=../../src/import_map.json bld.ts prepare-dist --log-level info
}
package() {
cd "${srcdir}/${_pkgbasename}"
- mkdir -p package/pkg-working/bin/tools/${_deno_arch}
- mkdir -p package/pkg-working/bin/tools/dart-sass
- mkdir -p package/pkg-working/bin/tools/deno_dom
- cp "${srcdir}/deno-dom-${_denodomver}/target/release/libplugin.so" "${srcdir}/${_pkgbasename}/package/pkg-working/bin/tools/deno_dom"
- ln -sfT /usr/bin/pandoc package/pkg-working/bin/tools/pandoc
- ln -sfT /usr/bin/deno package/pkg-working/bin/tools/${_deno_arch}/deno
- ln -sfT /usr/bin/sass package/pkg-working/bin/tools/dart-sass/sass
- ln -sfT /usr/bin/esbuild package/pkg-working/bin/tools/esbuild
+ mkdir -p package/pkg-working/bin/tools/${arch}/dart-sass
+ mkdir -p package/pkg-working/bin/tools/${arch}/deno_dom
+ cp "${srcdir}/deno-dom-${_denodomver}/target/release/libplugin.so" "${srcdir}/${_pkgbasename}/package/pkg-working/bin/tools/${arch}/deno_dom"
+ ln -sfT /usr/bin/pandoc package/pkg-working/bin/tools/${arch}/pandoc
+ ln -sfT /usr/bin/deno package/pkg-working/bin/tools/${arch}/deno
+ ln -sfT /usr/bin/sass package/pkg-working/bin/tools/${arch}/dart-sass/sass
+ ln -sfT /usr/bin/esbuild package/pkg-working/bin/tools/${arch}/esbuild
+ ln -sfT /usr/bin/typst package/pkg-working/bin/tools/${arch}/typst
## 2. Remove symlinks created by build script in ~/bin and ~/.local/bin directories
rm -f "$HOME/.local/bin/quarto"
rm -f "$HOME/bin/quarto"