From 478e297e9e3c2944fb20b750463db89f2dea1b72 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 24 Nov 2023 18:11:53 +0000 Subject: [PATCH 001/213] Initial work towards aliasing queries for SQL. --- .../server/src/api/controllers/row/alias.ts | 101 ++++++++++++++++++ packages/server/src/integrations/base/sql.ts | 1 + 2 files changed, 102 insertions(+) create mode 100644 packages/server/src/api/controllers/row/alias.ts diff --git a/packages/server/src/api/controllers/row/alias.ts b/packages/server/src/api/controllers/row/alias.ts new file mode 100644 index 0000000000..8111396ea9 --- /dev/null +++ b/packages/server/src/api/controllers/row/alias.ts @@ -0,0 +1,101 @@ +import { QueryJson, SearchFilters, Table, Row } from "@budibase/types" +import { getDatasourceAndQuery } from "../../../sdk/app/rows/utils" +import { cloneDeep } from "lodash" + +class AliasTables { + character: string + aliases: Record + tableAliases: Record + + constructor() { + this.character = "a" + this.aliases = {} + this.tableAliases = {} + } + + getAlias(tableName: string) { + if (this.aliases[tableName]) { + return this.aliases[tableName] + } + this.character = String.fromCharCode(this.character.charCodeAt(0) + 1) + this.aliases[tableName] = this.character + this.tableAliases[this.character] = tableName + return this.character + } + + aliasField(tableNames: string[], field: string) { + if (field.includes(".")) { + const [tableName, column] = field.split(".") + if (tableNames.includes(tableName)) { + return `${this.getAlias(tableName)}.${column}` + } + } + return field + } + + reverse(tableNames: string[], rows: T): T { + const process = (row: Row) => { + const final: Row = {} + for (let [key, value] of Object.entries(row)) { + if (!key.includes(".")) { + final[key] = value + } else { + const [alias, column] = key.split(".") + const tableName = this.tableAliases[alias] || alias + final[`${tableName}.${column}`] = value + } + } + return final + } + if (Array.isArray(rows)) { + return rows.map(row => process(row)) as T + } else { + return process(rows) as T + } + } + + async queryWithAliasing(tableNames: string[], json: QueryJson) { + json = cloneDeep(json) + const aliasField = (field: string) => this.aliasField(tableNames, field) + const aliasTable = (table: Table) => ({ + ...table, + name: this.getAlias(table.name), + }) + // run through the query json to update anywhere a table may be used + if (json.resource?.fields) { + json.resource.fields = json.resource.fields.map(field => + aliasField(field) + ) + } + if (json.filters) { + for (let [filterKey, filter] of Object.entries(json.filters)) { + if (typeof filter !== "object") { + continue + } + const aliasedFilters: typeof filter = {} + for (let key of Object.keys(filter)) { + aliasedFilters[aliasField(key)] = filter + } + json.filters[filterKey as keyof SearchFilters] = aliasedFilters + } + } + if (json.relationships) { + json.relationships = json.relationships.map(relationship => ({ + ...relationship, + tableName: this.getAlias(relationship.tableName), + })) + } + if (json.meta?.table) { + json.meta.table = aliasTable(json.meta.table) + } + if (json.meta?.tables) { + const aliasedTables: Record = {} + for (let [tableName, table] of Object.entries(json.meta.tables)) { + aliasedTables[this.getAlias(tableName)] = aliasTable(table) + } + json.meta.tables = aliasedTables + } + const response = await getDatasourceAndQuery(json) + return this.reverse(tableNames, response) + } +} diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index 29c8416b34..630c962a15 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -437,6 +437,7 @@ class InternalBuilder { read(knex: Knex, json: QueryJson, limit: number): KnexQuery { let { endpoint, resource, filters, paginate, relationships } = json + const tableName = endpoint.entityId // select all if not specified if (!resource) { From c16ad8614240cbb70f21179aeb2e6239916fcce2 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 24 Nov 2023 18:12:35 +0000 Subject: [PATCH 002/213] Updating reverse function. --- packages/server/src/api/controllers/row/alias.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/api/controllers/row/alias.ts b/packages/server/src/api/controllers/row/alias.ts index 8111396ea9..d4937186d9 100644 --- a/packages/server/src/api/controllers/row/alias.ts +++ b/packages/server/src/api/controllers/row/alias.ts @@ -33,7 +33,7 @@ class AliasTables { return field } - reverse(tableNames: string[], rows: T): T { + reverse(rows: T): T { const process = (row: Row) => { const final: Row = {} for (let [key, value] of Object.entries(row)) { @@ -96,6 +96,6 @@ class AliasTables { json.meta.tables = aliasedTables } const response = await getDatasourceAndQuery(json) - return this.reverse(tableNames, response) + return this.reverse(response) } } From cb7c1898f2d29ac52f6b943dc04dd716b9ba128e Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 27 Nov 2023 19:02:06 +0000 Subject: [PATCH 003/213] Getting basic aliasing working after some testing. --- .../api/controllers/row/ExternalRequest.ts | 19 +++++++------- .../server/src/api/controllers/row/alias.ts | 25 +++++++++++-------- packages/server/src/integrations/base/sql.ts | 11 +++++--- packages/server/src/sdk/app/rows/utils.ts | 4 +-- packages/types/src/sdk/search.ts | 2 ++ 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/packages/server/src/api/controllers/row/ExternalRequest.ts b/packages/server/src/api/controllers/row/ExternalRequest.ts index 7c98fecb9b..29851e457f 100644 --- a/packages/server/src/api/controllers/row/ExternalRequest.ts +++ b/packages/server/src/api/controllers/row/ExternalRequest.ts @@ -32,6 +32,7 @@ import { processObjectSync } from "@budibase/string-templates" import { cloneDeep } from "lodash/fp" import { processDates, processFormulas } from "../../../utilities/rowProcessor" import { db as dbCore } from "@budibase/backend-core" +import AliasTables from "./alias" import sdk from "../../../sdk" export interface ManyRelationship { @@ -178,13 +179,13 @@ function generateIdForRow( function getEndpoint(tableId: string | undefined, operation: string) { if (!tableId) { - return {} + throw new Error("Cannot get endpoint information - no table ID specified") } const { datasourceId, tableName } = breakExternalTableId(tableId) return { - datasourceId, - entityId: tableName, - operation, + datasourceId: datasourceId!, + entityId: tableName!, + operation: operation as Operation, } } @@ -704,7 +705,7 @@ export class ExternalRequest { // safety check, if there are no filters on deletion bad things happen if (Object.keys(filters).length !== 0) { const op = isMany ? Operation.DELETE : Operation.UPDATE - const body = isMany ? null : { [colName]: null } + const body = isMany ? undefined : { [colName]: null } promises.push( getDatasourceAndQuery({ endpoint: getEndpoint(tableId, op), @@ -807,7 +808,7 @@ export class ExternalRequest { } let json = { endpoint: { - datasourceId, + datasourceId: datasourceId!, entityId: tableName, operation, }, @@ -829,9 +830,9 @@ export class ExternalRequest { }, } - // can't really use response right now - const response = await getDatasourceAndQuery(json) - // handle many to many relationships now if we know the ID (could be auto increment) + const aliasing = new AliasTables(Object.keys(this.tables)) + const response = await aliasing.queryWithAliasing(json) + // handle many-to-many relationships now if we know the ID (could be auto increment) if (operation !== Operation.READ) { await this.handleManyRelationships( table._id || "", diff --git a/packages/server/src/api/controllers/row/alias.ts b/packages/server/src/api/controllers/row/alias.ts index d4937186d9..19be8db654 100644 --- a/packages/server/src/api/controllers/row/alias.ts +++ b/packages/server/src/api/controllers/row/alias.ts @@ -2,12 +2,14 @@ import { QueryJson, SearchFilters, Table, Row } from "@budibase/types" import { getDatasourceAndQuery } from "../../../sdk/app/rows/utils" import { cloneDeep } from "lodash" -class AliasTables { +export default class AliasTables { character: string aliases: Record tableAliases: Record + tableNames: string[] - constructor() { + constructor(tableNames: string[]) { + this.tableNames = tableNames this.character = "a" this.aliases = {} this.tableAliases = {} @@ -17,13 +19,15 @@ class AliasTables { if (this.aliases[tableName]) { return this.aliases[tableName] } - this.character = String.fromCharCode(this.character.charCodeAt(0) + 1) - this.aliases[tableName] = this.character - this.tableAliases[this.character] = tableName - return this.character + const char = this.character + this.aliases[tableName] = char + this.tableAliases[char] = tableName + this.character = String.fromCharCode(char.charCodeAt(0) + 1) + return char } - aliasField(tableNames: string[], field: string) { + aliasField(field: string) { + const tableNames = this.tableNames if (field.includes(".")) { const [tableName, column] = field.split(".") if (tableNames.includes(tableName)) { @@ -54,9 +58,9 @@ class AliasTables { } } - async queryWithAliasing(tableNames: string[], json: QueryJson) { + async queryWithAliasing(json: QueryJson) { json = cloneDeep(json) - const aliasField = (field: string) => this.aliasField(tableNames, field) + const aliasField = (field: string) => this.aliasField(field) const aliasTable = (table: Table) => ({ ...table, name: this.getAlias(table.name), @@ -82,7 +86,7 @@ class AliasTables { if (json.relationships) { json.relationships = json.relationships.map(relationship => ({ ...relationship, - tableName: this.getAlias(relationship.tableName), + alias: this.getAlias(relationship.tableName), })) } if (json.meta?.table) { @@ -95,6 +99,7 @@ class AliasTables { } json.meta.tables = aliasedTables } + json.endpoint.alias = this.getAlias(json.endpoint.entityId) const response = await getDatasourceAndQuery(json) return this.reverse(response) } diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index 630c962a15..3147e8c670 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -439,6 +439,9 @@ class InternalBuilder { let { endpoint, resource, filters, paginate, relationships } = json const tableName = endpoint.entityId + const alias = endpoint.alias + const aliased = alias ? alias : tableName + const tableAliased = alias ? `${tableName} as ${alias}` : tableName // select all if not specified if (!resource) { resource = { fields: [] } @@ -463,20 +466,20 @@ class InternalBuilder { foundLimit = paginate.limit } // start building the query - let query: KnexQuery = knex(tableName).limit(foundLimit) + let query: KnexQuery = knex(tableAliased).limit(foundLimit) if (endpoint.schema) { query = query.withSchema(endpoint.schema) } if (foundOffset) { query = query.offset(foundOffset) } - query = this.addFilters(query, filters, { tableName }) + query = this.addFilters(query, filters, { tableName: aliased }) // add sorting to pre-query query = this.addSorting(query, json) // @ts-ignore let preQuery: KnexQuery = knex({ // @ts-ignore - [tableName]: query, + [aliased]: query, }).select(selectStatement) // have to add after as well (this breaks MS-SQL) if (this.client !== SqlClient.MS_SQL) { @@ -485,7 +488,7 @@ class InternalBuilder { // handle joins query = this.addRelationships( preQuery, - tableName, + aliased, relationships, endpoint.schema ) diff --git a/packages/server/src/sdk/app/rows/utils.ts b/packages/server/src/sdk/app/rows/utils.ts index d0227c7c6b..c160aaba3f 100644 --- a/packages/server/src/sdk/app/rows/utils.ts +++ b/packages/server/src/sdk/app/rows/utils.ts @@ -1,13 +1,13 @@ import cloneDeep from "lodash/cloneDeep" import validateJs from "validate.js" -import { Row, Table, TableSchema } from "@budibase/types" +import { QueryJson, Row, Table, TableSchema } from "@budibase/types" import { FieldTypes } from "../../../constants" import { makeExternalQuery } from "../../../integrations/base/query" import { Format } from "../../../api/controllers/view/exporters" import sdk from "../.." import { isRelationshipColumn } from "../../../db/utils" -export async function getDatasourceAndQuery(json: any) { +export async function getDatasourceAndQuery(json: QueryJson) { const datasourceId = json.endpoint.datasourceId const datasource = await sdk.datasources.get(datasourceId) return makeExternalQuery(datasource, json) diff --git a/packages/types/src/sdk/search.ts b/packages/types/src/sdk/search.ts index 35fd148c05..1f9aa6c375 100644 --- a/packages/types/src/sdk/search.ts +++ b/packages/types/src/sdk/search.ts @@ -67,6 +67,7 @@ export interface RelationshipsJson { fromPrimary?: string toPrimary?: string tableName: string + alias?: string column: string } @@ -74,6 +75,7 @@ export interface QueryJson { endpoint: { datasourceId: string entityId: string + alias?: string operation: Operation schema?: string } From 65cddae9dac4f511c70634e4885987b672989c13 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 28 Nov 2023 18:43:38 +0000 Subject: [PATCH 004/213] Getting relationship aliasing working. --- .../server/src/api/controllers/row/alias.ts | 16 +++++++- packages/server/src/integrations/base/sql.ts | 39 ++++++++++++++----- packages/types/src/sdk/search.ts | 2 +- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/packages/server/src/api/controllers/row/alias.ts b/packages/server/src/api/controllers/row/alias.ts index 19be8db654..0c7a4bb8a0 100644 --- a/packages/server/src/api/controllers/row/alias.ts +++ b/packages/server/src/api/controllers/row/alias.ts @@ -58,6 +58,16 @@ export default class AliasTables { } } + aliasMap(tableNames: (string | undefined)[]) { + const map: Record = {} + for (let tableName of tableNames) { + if (tableName) { + map[tableName] = this.getAlias(tableName) + } + } + return map + } + async queryWithAliasing(json: QueryJson) { json = cloneDeep(json) const aliasField = (field: string) => this.aliasField(field) @@ -86,7 +96,11 @@ export default class AliasTables { if (json.relationships) { json.relationships = json.relationships.map(relationship => ({ ...relationship, - alias: this.getAlias(relationship.tableName), + aliases: this.aliasMap([ + relationship.through, + relationship.tableName, + json.endpoint.entityId, + ]), })) } if (json.meta?.table) { diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index 3147e8c670..f3f574b1af 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -330,6 +330,17 @@ class InternalBuilder { return query } + tableNameWithSchema( + tableName: string, + opts?: { alias?: string; schema?: string } + ) { + let withSchema = opts?.schema ? `${opts.schema}.${tableName}` : tableName + if (opts?.alias) { + withSchema += ` as ${opts.alias}` + } + return withSchema + } + addRelationships( query: KnexQuery, fromTable: string, @@ -339,9 +350,12 @@ class InternalBuilder { if (!relationships) { return query } - const tableSets: Record = {} + const tableSets: Record = {} + // add up all aliases + let aliases: Record = {} // aggregate into table sets (all the same to tables) for (let relationship of relationships) { + aliases = { ...aliases, ...relationship.aliases } const keyObj: { toTable: string; throughTable: string | undefined } = { toTable: relationship.tableName, throughTable: undefined, @@ -358,10 +372,17 @@ class InternalBuilder { } for (let [key, relationships] of Object.entries(tableSets)) { const { toTable, throughTable } = JSON.parse(key) - const toTableWithSchema = schema ? `${schema}.${toTable}` : toTable - const throughTableWithSchema = schema - ? `${schema}.${throughTable}` - : throughTable + const toAlias = aliases[toTable], + throughAlias = aliases[throughTable], + fromAlias = aliases[fromTable] + let toTableWithSchema = this.tableNameWithSchema(toTable, { + alias: toAlias, + schema, + }) + let throughTableWithSchema = this.tableNameWithSchema(throughTable, { + alias: throughAlias, + schema, + }) if (!throughTable) { // @ts-ignore query = query.leftJoin(toTableWithSchema, function () { @@ -369,7 +390,7 @@ class InternalBuilder { const from = relationship.from, to = relationship.to // @ts-ignore - this.orOn(`${fromTable}.${from}`, "=", `${toTable}.${to}`) + this.orOn(`${fromTable}.${from}`, "=", `${toAlias}.${to}`) } }) } else { @@ -381,9 +402,9 @@ class InternalBuilder { const from = relationship.from // @ts-ignore this.orOn( - `${fromTable}.${fromPrimary}`, + `${fromAlias}.${fromPrimary}`, "=", - `${throughTable}.${from}` + `${throughAlias}.${from}` ) } }) @@ -392,7 +413,7 @@ class InternalBuilder { const toPrimary = relationship.toPrimary const to = relationship.to // @ts-ignore - this.orOn(`${toTable}.${toPrimary}`, `${throughTable}.${to}`) + this.orOn(`${toAlias}.${toPrimary}`, `${throughAlias}.${to}`) } }) } diff --git a/packages/types/src/sdk/search.ts b/packages/types/src/sdk/search.ts index 1f9aa6c375..a4045c2558 100644 --- a/packages/types/src/sdk/search.ts +++ b/packages/types/src/sdk/search.ts @@ -67,7 +67,7 @@ export interface RelationshipsJson { fromPrimary?: string toPrimary?: string tableName: string - alias?: string + aliases?: Record column: string } From 649025ca124a4b9b7f0714d9621edcb3c4ae3424 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 28 Nov 2023 18:45:05 +0000 Subject: [PATCH 005/213] Fixing missed from. --- packages/server/src/integrations/base/sql.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index f3f574b1af..c419edc805 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -390,7 +390,7 @@ class InternalBuilder { const from = relationship.from, to = relationship.to // @ts-ignore - this.orOn(`${fromTable}.${from}`, "=", `${toAlias}.${to}`) + this.orOn(`${fromAlias}.${from}`, "=", `${toAlias}.${to}`) } }) } else { From 5c4dc0dc8351310f6ab9c022594386a4543c47f6 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 1 Dec 2023 14:14:44 +0000 Subject: [PATCH 006/213] Fixing issue with aliasing. --- packages/server/src/integrations/base/sql.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index c419edc805..57af95eabb 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -372,9 +372,9 @@ class InternalBuilder { } for (let [key, relationships] of Object.entries(tableSets)) { const { toTable, throughTable } = JSON.parse(key) - const toAlias = aliases[toTable], - throughAlias = aliases[throughTable], - fromAlias = aliases[fromTable] + const toAlias = aliases[toTable] || toTable, + throughAlias = aliases[throughTable] || throughTable, + fromAlias = aliases[fromTable] || fromTable let toTableWithSchema = this.tableNameWithSchema(toTable, { alias: toAlias, schema, From 7eccbb851dac11b36e936ae52a67500f99cc7a52 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 1 Dec 2023 15:27:49 +0000 Subject: [PATCH 007/213] Fixing issues with other SQL functions than just reading. --- .../server/src/api/controllers/row/alias.ts | 2 +- packages/server/src/integrations/base/sql.ts | 46 +++++++++---------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/packages/server/src/api/controllers/row/alias.ts b/packages/server/src/api/controllers/row/alias.ts index 0c7a4bb8a0..fc00b505c4 100644 --- a/packages/server/src/api/controllers/row/alias.ts +++ b/packages/server/src/api/controllers/row/alias.ts @@ -88,7 +88,7 @@ export default class AliasTables { } const aliasedFilters: typeof filter = {} for (let key of Object.keys(filter)) { - aliasedFilters[aliasField(key)] = filter + aliasedFilters[aliasField(key)] = filter[key] } json.filters[filterKey as keyof SearchFilters] = aliasedFilters } diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index 57af95eabb..14bcb532cc 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -421,12 +421,24 @@ class InternalBuilder { return query.limit(BASE_LIMIT) } - create(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { - const { endpoint, body } = json - let query: KnexQuery = knex(endpoint.entityId) + knexWithAlias( + knex: Knex, + endpoint: { entityId: string; alias?: string; schema?: string } + ): { query: KnexQuery; name: string } { + const tableName = endpoint.entityId + const alias = endpoint.alias + const aliased = alias ? alias : tableName + const tableAliased = alias ? `${tableName} as ${alias}` : tableName + let query = knex(tableAliased) if (endpoint.schema) { query = query.withSchema(endpoint.schema) } + return { query, name: aliased } + } + + create(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { + const { endpoint, body } = json + let { query } = this.knexWithAlias(knex, endpoint) const parsedBody = parseBody(body) // make sure no null values in body for creation for (let [key, value] of Object.entries(parsedBody)) { @@ -445,10 +457,7 @@ class InternalBuilder { bulkCreate(knex: Knex, json: QueryJson): KnexQuery { const { endpoint, body } = json - let query: KnexQuery = knex(endpoint.entityId) - if (endpoint.schema) { - query = query.withSchema(endpoint.schema) - } + let { query } = this.knexWithAlias(knex, endpoint) if (!Array.isArray(body)) { return query } @@ -459,10 +468,6 @@ class InternalBuilder { read(knex: Knex, json: QueryJson, limit: number): KnexQuery { let { endpoint, resource, filters, paginate, relationships } = json - const tableName = endpoint.entityId - const alias = endpoint.alias - const aliased = alias ? alias : tableName - const tableAliased = alias ? `${tableName} as ${alias}` : tableName // select all if not specified if (!resource) { resource = { fields: [] } @@ -487,10 +492,9 @@ class InternalBuilder { foundLimit = paginate.limit } // start building the query - let query: KnexQuery = knex(tableAliased).limit(foundLimit) - if (endpoint.schema) { - query = query.withSchema(endpoint.schema) - } + + let { query, name: aliased } = this.knexWithAlias(knex, endpoint) + query = query.limit(foundLimit) if (foundOffset) { query = query.offset(foundOffset) } @@ -518,10 +522,7 @@ class InternalBuilder { update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { const { endpoint, body, filters } = json - let query: KnexQuery = knex(endpoint.entityId) - if (endpoint.schema) { - query = query.withSchema(endpoint.schema) - } + let { query } = this.knexWithAlias(knex, endpoint) const parsedBody = parseBody(body) query = this.addFilters(query, filters, { tableName: endpoint.entityId }) // mysql can't use returning @@ -534,11 +535,8 @@ class InternalBuilder { delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { const { endpoint, filters } = json - let query: KnexQuery = knex(endpoint.entityId) - if (endpoint.schema) { - query = query.withSchema(endpoint.schema) - } - query = this.addFilters(query, filters, { tableName: endpoint.entityId }) + let { query, name: aliased } = this.knexWithAlias(knex, endpoint) + query = this.addFilters(query, filters, { tableName: aliased }) // mysql can't use returning if (opts.disableReturning) { return query.delete() From 3ce00c42a2e9751bcfb17d906b8b8a8c85f04752 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 18 Jan 2024 18:13:11 +0000 Subject: [PATCH 008/213] Adding SQL logging capabilities. --- packages/server/src/environment.ts | 1 + packages/server/src/integrations/base/sql.ts | 12 + .../src/integrations/microsoftSqlServer.ts | 1 + packages/server/src/integrations/mysql.ts | 1 + packages/server/src/integrations/oracle.ts | 1 + packages/server/src/integrations/postgres.ts | 4 +- yarn.lock | 660 +----------------- 7 files changed, 55 insertions(+), 625 deletions(-) diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index f692a8b6cf..f46abe5b16 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -67,6 +67,7 @@ const environment = { DISABLE_RATE_LIMITING: process.env.DISABLE_RATE_LIMITING, MULTI_TENANCY: process.env.MULTI_TENANCY, ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS, + ENABLE_SQL_LOGGING: process.env.ENABLE_SQL_LOGGING, SELF_HOSTED: process.env.SELF_HOSTED, HTTP_MB_LIMIT: process.env.HTTP_MB_LIMIT, FORKED_PROCESS_NAME: process.env.FORKED_PROCESS_NAME || "main", diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index 14bcb532cc..3375e175e6 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -671,6 +671,18 @@ class SqlQueryBuilder extends SqlTableQueryBuilder { } return results.length ? results : [{ [operation.toLowerCase()]: true }] } + + log(query: string, values?: any[]) { + if (!environment.ENABLE_SQL_LOGGING) { + return + } + const sqlClient = this.getSqlClient() + let string = `[SQL] [${sqlClient.toUpperCase()}] query="${query}"` + if (values) { + string += ` values="${values.join(", ")}"` + } + console.log(string) + } } export default SqlQueryBuilder diff --git a/packages/server/src/integrations/microsoftSqlServer.ts b/packages/server/src/integrations/microsoftSqlServer.ts index d0a06d4476..e063933503 100644 --- a/packages/server/src/integrations/microsoftSqlServer.ts +++ b/packages/server/src/integrations/microsoftSqlServer.ts @@ -329,6 +329,7 @@ class SqlServerIntegration extends Sql implements DatasourcePlus { operation === Operation.CREATE ? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;` : query.sql + this.log(sql, query.bindings) return await request.query(sql) } catch (err: any) { let readableMessage = getReadableErrorMessage( diff --git a/packages/server/src/integrations/mysql.ts b/packages/server/src/integrations/mysql.ts index 8ec73307f4..6eebda8df5 100644 --- a/packages/server/src/integrations/mysql.ts +++ b/packages/server/src/integrations/mysql.ts @@ -261,6 +261,7 @@ class MySQLIntegration extends Sql implements DatasourcePlus { const bindings = opts?.disableCoercion ? baseBindings : bindingTypeCoerce(baseBindings) + this.log(query.sql, bindings) // Node MySQL is callback based, so we must wrap our call in a promise const response = await this.client!.query(query.sql, bindings) return response[0] diff --git a/packages/server/src/integrations/oracle.ts b/packages/server/src/integrations/oracle.ts index e9a2dc7998..1a1e440410 100644 --- a/packages/server/src/integrations/oracle.ts +++ b/packages/server/src/integrations/oracle.ts @@ -368,6 +368,7 @@ class OracleIntegration extends Sql implements DatasourcePlus { const options: ExecuteOptions = { autoCommit: true } const bindings: BindParameters = query.bindings || [] + this.log(query.sql, bindings) return await connection.execute(query.sql, bindings, options) } finally { if (connection) { diff --git a/packages/server/src/integrations/postgres.ts b/packages/server/src/integrations/postgres.ts index 78955c06dc..f8cd2b62fc 100644 --- a/packages/server/src/integrations/postgres.ts +++ b/packages/server/src/integrations/postgres.ts @@ -262,7 +262,9 @@ class PostgresIntegration extends Sql implements DatasourcePlus { } } try { - return await client.query(query.sql, query.bindings || []) + const bindings = query.bindings || [] + this.log(query.sql, bindings) + return await client.query(query.sql, bindings) } catch (err: any) { await this.closeConnection() let readableMessage = getReadableErrorMessage( diff --git a/yarn.lock b/yarn.lock index 91697cd151..fa746b9d72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -625,13 +625,6 @@ dependencies: tslib "^2.5.0" -"@aws/dynamodb-auto-marshaller@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@aws/dynamodb-auto-marshaller/-/dynamodb-auto-marshaller-0.7.1.tgz#70676c056e4ecb798c08ec2e398a3d93e703858d" - integrity sha512-LeURlf6/avrfFo9+4Yht9J3CUTJ72yoBpm1FOUmlexuHNW4Ka61tG30w3ZDCXXXmCO2rG0k3ywAgNJEo3WPbyw== - dependencies: - tslib "^1.8.1" - "@azure/abort-controller@^1.0.0", "@azure/abort-controller@^1.0.4": version "1.1.0" resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.1.0.tgz#788ee78457a55af8a1ad342acb182383d2119249" @@ -1980,7 +1973,7 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.15.4", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.23.8" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.8.tgz#8ee6fe1ac47add7122902f257b8ddf55c898f650" integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== @@ -2638,14 +2631,6 @@ teeny-request "^8.0.0" uuid "^8.0.0" -"@grpc/grpc-js@1.9.7": - version "1.9.7" - resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.9.7.tgz#7d0e29bc162287bee2523901c9bc9320d8402397" - integrity sha512-yMaA/cIsRhGzW3ymCNpdlPcInXcovztlgu/rirThj2b87u3RzWUszliOqZ/pldy7yhmJPS8uwog+kZSTa4A0PQ== - dependencies: - "@grpc/proto-loader" "^0.7.8" - "@types/node" ">=12.12.47" - "@grpc/grpc-js@~1.8.0": version "1.8.21" resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.8.21.tgz#d282b122c71227859bf6c5866f4c40f4a2696513" @@ -2654,7 +2639,7 @@ "@grpc/proto-loader" "^0.7.0" "@types/node" ">=12.12.47" -"@grpc/proto-loader@0.7.10", "@grpc/proto-loader@^0.7.0", "@grpc/proto-loader@^0.7.8": +"@grpc/proto-loader@^0.7.0": version "0.7.10" resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.7.10.tgz#6bf26742b1b54d0a473067743da5d3189d06d720" integrity sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ== @@ -2676,20 +2661,6 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@hubspot/api-client@7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@hubspot/api-client/-/api-client-7.1.2.tgz#a405b0a18b8caa27f129fd510b2555e5a5cc2708" - integrity sha512-JVQqh0fdHf97ePk0Hg/7BJsiXNlS9HQRPiM/CLgvVWt5CIviSLQ/kHLZXREmZqTWu7BisjCgHxnSx/d7gRdr2g== - dependencies: - bluebird "^3.7.2" - bottleneck "^2.19.5" - btoa "^1.2.1" - es6-promise "^4.2.4" - form-data "^2.5.0" - lodash "^4.17.21" - node-fetch "^2.6.0" - url-parse "^1.4.3" - "@humanwhocodes/config-array@^0.11.13": version "0.11.13" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" @@ -3341,13 +3312,6 @@ dependencies: lodash "^4.17.21" -"@koa/cors@^3.1.0": - version "3.4.3" - resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.4.3.tgz#d669ee6e8d6e4f0ec4a7a7b0a17e7a3ed3752ebb" - integrity sha512-WPXQUaAeAMVaLTEFpoq3T2O1C+FstkjJnDQqy95Ck1UdILajsRhu6mhJ8H2f4NFPRBoCNN+qywTJfq/gGki5mw== - dependencies: - vary "^1.1.2" - "@koa/router@8.0.8": version "8.0.8" resolved "https://registry.yarnpkg.com/@koa/router/-/router-8.0.8.tgz#95f32d11373d03d89dcb63fabe9ac6f471095236" @@ -3956,14 +3920,6 @@ is-module "^1.0.0" resolve "^1.19.0" -"@rollup/plugin-replace@^2.4.2": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a" - integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== - dependencies: - "@rollup/pluginutils" "^3.1.0" - magic-string "^0.25.7" - "@rollup/plugin-replace@^5.0.2", "@rollup/plugin-replace@^5.0.3": version "5.0.5" resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-5.0.5.tgz#33d5653dce6d03cb24ef98bef7f6d25b57faefdf" @@ -4006,23 +3962,6 @@ estree-walker "^2.0.2" picomatch "^2.3.1" -"@roxi/routify@2.18.0": - version "2.18.0" - resolved "https://registry.yarnpkg.com/@roxi/routify/-/routify-2.18.0.tgz#8f88bedd936312d0dbe44cbc11ab179b1f938ec2" - integrity sha512-MVB50HN+VQWLzfjLplcBjsSBvwOiExKOmht2DuWR3WQ60JxQi9pSejkB06tFVkFKNXz2X5iYtKDqKBTdae/gRg== - dependencies: - "@roxi/ssr" "^0.2.1" - "@types/node" ">=4.2.0 < 13" - chalk "^4.0.0" - cheap-watch "^1.0.2" - commander "^7.1.0" - configent "^2.1.4" - esm "^3.2.25" - fs-extra "^9.0.1" - log-symbols "^3.0.0" - picomatch "^2.2.2" - rollup-pluginutils "^2.8.2" - "@roxi/routify@2.18.12": version "2.18.12" resolved "https://registry.yarnpkg.com/@roxi/routify/-/routify-2.18.12.tgz#901ca95b96f274ddddaefbf18424557ee1ae3fae" @@ -4104,11 +4043,6 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== -"@sindresorhus/is@^4.0.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" - integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== - "@sinonjs/commons@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" @@ -4932,13 +4866,6 @@ dependencies: defer-to-connect "^1.0.1" -"@szmarczak/http-timer@^4.0.5": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" - integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== - dependencies: - defer-to-connect "^2.0.0" - "@techpass/passport-openidconnect@0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@techpass/passport-openidconnect/-/passport-openidconnect-0.3.2.tgz#f8fd5d97256286665dbf26dac92431f977ab1e63" @@ -4950,17 +4877,6 @@ request "^2.88.0" webfinger "^0.4.2" -"@techpass/passport-openidconnect@^0.3.0": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@techpass/passport-openidconnect/-/passport-openidconnect-0.3.3.tgz#6c01c78bd8da0ca8917378dfbe18024702620352" - integrity sha512-i2X/CofjnGBqpTmw6b+Ex3Co/NrR2xjnIHvnOJk62XIlJJHNSTwmhJ1PkXoA5RGKlxZWchADFGjLTJnebvRj7A== - dependencies: - base64url "^3.0.1" - oauth "^0.9.15" - passport-strategy "^1.0.0" - request "^2.88.0" - webfinger "^0.4.2" - "@techteamer/ocsp@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@techteamer/ocsp/-/ocsp-1.0.0.tgz#7b82b02093fbe351e915bb37685ac1ac5a1233d3" @@ -5133,16 +5049,6 @@ "@types/connect" "*" "@types/node" "*" -"@types/cacheable-request@^6.0.1": - version "6.0.3" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" - integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== - dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "^3.1.4" - "@types/node" "*" - "@types/responselike" "^1.0.0" - "@types/caseless@*": version "0.12.2" resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" @@ -5307,11 +5213,6 @@ resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.3.tgz#ef8e3d1a8d46c387f04ab0f2e8ab8cb0c5078661" integrity sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA== -"@types/http-cache-semantics@*": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" - integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== - "@types/http-errors@*": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.1.tgz#20172f9578b225f6c7da63446f56d4ce108d5a65" @@ -5373,13 +5274,6 @@ resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw== -"@types/keyv@^3.1.4": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" - integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== - dependencies: - "@types/node" "*" - "@types/koa-compose@*": version "3.2.5" resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.5.tgz#85eb2e80ac50be95f37ccf8c407c09bbe3468e9d" @@ -5387,29 +5281,13 @@ dependencies: "@types/koa" "*" -"@types/koa-passport@^4.0.3": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/koa-passport/-/koa-passport-4.0.3.tgz#063ec6310edee76cf854aadaa717b97f04b104fb" - integrity sha512-tNMYd/bcv0Zw7fc0CzEBYM9uUzVtn4XWzdUYfkTgSkEljP6nap7eI4E5x43ukrUQvztgXSYFkz3Uk+ujFeUzTg== - dependencies: - "@types/koa" "*" - "@types/passport" "*" - -"@types/koa-send@*", "@types/koa-send@^4.1.6": +"@types/koa-send@^4.1.6": version "4.1.6" resolved "https://registry.yarnpkg.com/@types/koa-send/-/koa-send-4.1.6.tgz#15d90e95e3ccce669a15b6a3c56c3a650a167cea" integrity sha512-vgnNGoOJkx7FrF0Jl6rbK1f8bBecqAchKpXtKuXzqIEdXTDO6dsSTjr+eZ5m7ltSjH4K/E7auNJEQCAd0McUPA== dependencies: "@types/koa" "*" -"@types/koa-static@^4.0.2": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/koa-static/-/koa-static-4.0.4.tgz#ce6f2a5d14cc7ef19f9bf6ee8e4f3eadfcc77323" - integrity sha512-j1AUzzl7eJYEk9g01hNTlhmipFh8RFbOQmaMNLvLcNNAkPw0bdTs3XTa3V045XFlrWN0QYnblbDJv2RzawTn6A== - dependencies: - "@types/koa" "*" - "@types/koa-send" "*" - "@types/koa@*": version "2.13.5" resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.5.tgz#64b3ca4d54e08c0062e89ec666c9f45443b21a61" @@ -5438,13 +5316,6 @@ "@types/koa-compose" "*" "@types/node" "*" -"@types/koa__cors@^3.1.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/koa__cors/-/koa__cors-3.3.1.tgz#0ec7543c4c620fd23451bfdd3e21b9a6aadedccd" - integrity sha512-aFGYhTFW7651KhmZZ05VG0QZJre7QxBxDj2LF1lf6GA/wSXEfKVAJxiQQWzRV4ZoMzQIO8vJBXKsUcRuvYK9qw== - dependencies: - "@types/koa" "*" - "@types/koa__router@8.0.8": version "8.0.8" resolved "https://registry.yarnpkg.com/@types/koa__router/-/koa__router-8.0.8.tgz#b1e0e9a512498777d3366bbdf0e853df27ec831c" @@ -5546,42 +5417,21 @@ dependencies: undici-types "~5.26.4" -"@types/node@>=4.2.0 < 13", "@types/node@^12.20.52": - version "12.20.55" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" - integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== - "@types/node@>=8.0.0 <15": version "14.18.37" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.37.tgz#0bfcd173e8e1e328337473a8317e37b3b14fd30d" integrity sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg== -"@types/node@>=8.1.0": - version "20.11.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.2.tgz#39cea3fe02fbbc2f80ed283e94e1d24f2d3856fb" - integrity sha512-cZShBaVa+UO1LjWWBPmWRR4+/eY/JR/UIEcDlVsw3okjWEu+rB7/mH6X3B/L+qJVHDLjk9QW/y2upp9wp1yDXA== - dependencies: - undici-types "~5.26.4" - -"@types/nodemailer@^6.4.4": - version "6.4.14" - resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.14.tgz#5c81a5e856db7f8ede80013e6dbad7c5fb2283e2" - integrity sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA== - dependencies: - "@types/node" "*" +"@types/node@^12.20.52": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== -"@types/oauth@*": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.4.tgz#dcbab5efa2f34f312b915f80685760ccc8111e0a" - integrity sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A== - dependencies: - "@types/node" "*" - "@types/oracledb@5.2.2": version "5.2.2" resolved "https://registry.yarnpkg.com/@types/oracledb/-/oracledb-5.2.2.tgz#ae7ba795969e3bbd8d57ab141873a1aa012b86cd" @@ -5590,37 +5440,6 @@ "@types/node" "*" dotenv "^8.2.0" -"@types/passport-google-oauth@^1.0.42": - version "1.0.45" - resolved "https://registry.yarnpkg.com/@types/passport-google-oauth/-/passport-google-oauth-1.0.45.tgz#c986c787ec9706b4a596d2bae43342b50b54973d" - integrity sha512-O3Y3DDKnf9lR8+DSaUOCEGF6aFjVYdI8TLhQYtySZ3Sq75c5tGYJ0KJRDZw0GsyLD/Que0nqFkP/GnDVwZZL9w== - dependencies: - "@types/express" "*" - "@types/passport" "*" - -"@types/passport-microsoft@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/passport-microsoft/-/passport-microsoft-1.0.0.tgz#a2ddc2200843570d38c35c53f6388e33df915b58" - integrity sha512-vD9ajSUc9Sz/8gdCj0ODUbPYQDxcI/imIDdgMPh//c5yMK/PgV6SNUXFLBzJo89Y30LU6bYAfXKn40WJqtMBiA== - dependencies: - "@types/passport-oauth2" "*" - -"@types/passport-oauth2@*": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@types/passport-oauth2/-/passport-oauth2-1.4.15.tgz#34f2684f53aad36e664cd01ca9879224229f47e7" - integrity sha512-9cUTP/HStNSZmhxXGuRrBJfEWzIEJRub2eyJu3CvkA+8HAMc9W3aKdFhVq+Qz1hi42qn+GvSAnz3zwacDSYWpw== - dependencies: - "@types/express" "*" - "@types/oauth" "*" - "@types/passport" "*" - -"@types/passport@*": - version "1.0.16" - resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.16.tgz#5a2918b180a16924c4d75c31254c31cdca5ce6cf" - integrity sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A== - dependencies: - "@types/express" "*" - "@types/pg@8.6.6": version "8.6.6" resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.6.6.tgz#21cdf873a3e345a6e78f394677e3b3b1b543cb80" @@ -5825,13 +5644,6 @@ dependencies: "@types/node" "*" -"@types/responselike@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" - integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== - dependencies: - "@types/node" "*" - "@types/rimraf@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.2.tgz#a63d175b331748e5220ad48c901d7bbf1f44eef8" @@ -5860,13 +5672,6 @@ dependencies: "@types/node" "*" -"@types/server-destroy@^1.0.1": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/server-destroy/-/server-destroy-1.0.3.tgz#2460932ea3a02a70ec99669c8f40ff089a5b8a2b" - integrity sha512-Qq0fn70C7TLDG1W9FCblKufNWW1OckQ41dVKV2Dku5KdZF7bexezG4e2WBaBKhdwL3HZ+cYCEIKwg2BRgzrWmA== - dependencies: - "@types/node" "*" - "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -5948,7 +5753,7 @@ dependencies: "@types/node" "*" -"@types/uuid@8.3.4", "@types/uuid@^8.3.4": +"@types/uuid@8.3.4": version "8.3.4" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== @@ -6290,6 +6095,11 @@ js-yaml "^3.10.0" tslib "^2.4.0" +"@zerodevx/svelte-json-view@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@zerodevx/svelte-json-view/-/svelte-json-view-1.0.7.tgz#abf3efa71dedcb3e9d16bc9cc61d5ea98c8d00b1" + integrity sha512-yW0MV+9BCKOwzt3h86y3xDqYdI5st+Rxk+L5pa0Utq7nlPD+VvxyhL7R1gJoLxQvWwjyAvY/fyUCFTdwDyI14w== + "@zkochan/js-yaml@0.0.6": version "0.0.6" resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826" @@ -6332,7 +6142,7 @@ abortcontroller-polyfill@^1.4.0: resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== -abstract-leveldown@^6.2.1, abstract-leveldown@^6.3.0: +abstract-leveldown@^6.2.1: version "6.3.0" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a" integrity sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ== @@ -6854,13 +6664,6 @@ async-retry@^1.3.3: dependencies: retry "0.13.1" -async@^2.6.3: - version "2.6.4" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" - async@^3.2.1, async@^3.2.3: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" @@ -7234,11 +7037,6 @@ bootstrap@3.4.1: resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-3.4.1.tgz#c3a347d419e289ad11f4033e3c4132b87c081d72" integrity sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA== -bottleneck@^2.19.5: - version "2.19.5" - resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91" - integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw== - bowser@^2.11.0: version "2.11.0" resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" @@ -7387,11 +7185,6 @@ bson@^5.4.0: resolved "https://registry.yarnpkg.com/bson/-/bson-5.4.0.tgz#0eea77276d490953ad8616b483298dbff07384c6" integrity sha512-WRZ5SQI5GfUuKnPTNmAYPiKIof3ORXAF4IRU5UcgmivNIon01rWQlw5RUH954dpu8yGL8T59YShVddIPaU/gFA== -btoa@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" - integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== - buffer-alloc-unsafe@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" @@ -7405,7 +7198,7 @@ buffer-alloc@^1.2.0: buffer-alloc-unsafe "^1.1.0" buffer-fill "^1.0.0" -buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: +buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== @@ -7590,11 +7383,6 @@ cache-content-type@^1.0.0: mime-types "^2.1.18" ylru "^1.2.0" -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== - cacheable-request@^2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" @@ -7621,19 +7409,6 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" -cacheable-request@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" - integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" @@ -7672,52 +7447,6 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -camunda-8-credentials-from-env@^1.1.1, camunda-8-credentials-from-env@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/camunda-8-credentials-from-env/-/camunda-8-credentials-from-env-1.2.2.tgz#abe5d216e7e4cfc970e0463e9aa5e802487b1062" - integrity sha512-uj2PY5/IoAgu0cHmeEUp+qmSXCtpQafStzGJ8ORYvyupBN/gVpdP9X+A+UlQRCGmApcaIuPUw8/9FsXig5NWXg== - dependencies: - neon-env "^0.1.1" - -camunda-8-sdk@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/camunda-8-sdk/-/camunda-8-sdk-0.15.0.tgz#13754dca499d16802675b6f2790e2d06bd8034d6" - integrity sha512-felyQU+rD8uupPjBArmyy0E/k9mrmeZvfFliF3y/pxYkGBoaC5kjDHDsx+hNpbnIwShET0RLjklit7f+98yIBw== - dependencies: - camunda-console-client "^0.9.1" - camunda-tasklist-client "0.9.5" - operate-api-client "1.2.3" - optimize-api-client "^1.0.3" - zeebe-node "^8.2.5" - -camunda-console-client@^0.9.1: - version "0.9.2" - resolved "https://registry.yarnpkg.com/camunda-console-client/-/camunda-console-client-0.9.2.tgz#137dbd2e61bb5bbfff38aebe5d53e775653aabb8" - integrity sha512-ni+7lSc5oG0FevCagrBV6juZzwcQ4ciATBZxyOMFQK0yVTmZxOUz5efN9XWP4E36PGpuqALQXsViUDlGZcfZBA== - dependencies: - camunda-8-credentials-from-env "^1.2.2" - camunda-saas-oauth "^1.2.4" - debug "^4.3.4" - dotenv "^16.3.1" - got "^11.8.6" - -camunda-saas-oauth@^1.2.0, camunda-saas-oauth@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/camunda-saas-oauth/-/camunda-saas-oauth-1.2.4.tgz#348a8422f266dafed98cf2a73046aa62c89d03f2" - integrity sha512-AO/kcnZXcsodwM3qgMZj/5wn8SBoKmSDpuFYUpPS+HqQhG9GvWY8noBx/4pvX3gYPKiPTYi9/e9ApAe02NARzA== - dependencies: - camunda-8-credentials-from-env "^1.2.2" - got "^11.8.5" - -camunda-tasklist-client@0.9.5: - version "0.9.5" - resolved "https://registry.yarnpkg.com/camunda-tasklist-client/-/camunda-tasklist-client-0.9.5.tgz#c0f2685ef7fb7fdb198a37e5b35a911e3b233b28" - integrity sha512-gipH8ON/ttTgLfleWecQith1g9SpC5Q8CoLXFq2yw3cVJ1JVrcn0ArtgCxA1QCgtZBlV7EuGt9QWGc9UCfbbGw== - dependencies: - camunda-8-credentials-from-env "^1.1.1" - camunda-saas-oauth "^1.2.0" - gotql "^2.1.0-alpha1" - caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -7811,7 +7540,7 @@ charenc@0.0.2: resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== -cheap-watch@^1.0.2, cheap-watch@^1.0.4: +cheap-watch@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/cheap-watch/-/cheap-watch-1.0.4.tgz#0bcb4a3a8fbd9d5327936493f6b56baa668d8fef" integrity sha512-QR/9FrtRL5fjfUJBhAKCdi0lSRQ3rVRRum3GF9wDKp2TJbEIMGhUEr2yU8lORzm9Isdjx7/k9S0DFDx+z5VGtw== @@ -8138,7 +7867,7 @@ commander@^5.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^7.0.0, commander@^7.1.0, commander@^7.2.0: +commander@^7.0.0, commander@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== @@ -8247,7 +7976,7 @@ config-chain@^1.1.13: ini "^1.3.4" proto-list "~1.2.1" -configent@^2.1.4, configent@^2.2.0: +configent@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/configent/-/configent-2.2.0.tgz#2de230fc43f22c47cfd99016aa6962d6f9546994" integrity sha512-yIN6zfOWk2nycNJ2JFNiWEai0oiqAhISIht8+pbEBP8bdcpwoQ74AhCZPbUv9aRVJwo7wh1MbCBDUV44UJa7Kw== @@ -8271,14 +8000,6 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== -console-stamp@^3.0.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/console-stamp/-/console-stamp-3.1.2.tgz#35dac393e16069a4d9d37b71ca6d5d13d7f3f8fd" - integrity sha512-ab66x3NxOTxPuq71dI6gXEiw2X6ql4Le5gZz0bm7FW3FSCB00eztra/oQUuCoCGlsyKOxtULnHwphzMrRtzMBg== - dependencies: - chalk "^4.1.2" - dateformat "^4.6.3" - consolidate@^0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.16.0.tgz#a11864768930f2f19431660a65906668f5fbdc16" @@ -8771,7 +8492,7 @@ dateformat@^4.6.3: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== -dayjs@^1.10.8, dayjs@^1.8.15: +dayjs@^1.10.8: version "1.11.10" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== @@ -8821,7 +8542,7 @@ dd-trace@5.0.0: semver "^7.5.4" tlhunter-sorted-set "^0.1.0" -debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: +debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -8870,13 +8591,6 @@ decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" @@ -9002,11 +8716,6 @@ defer-to-connect@^1.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== -defer-to-connect@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== - deferred-leveldown@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz#2cef1f111e1c57870d8bbb8af2650e587cd2f5b4" @@ -9050,11 +8759,6 @@ defined@^1.0.0: resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== -defined@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-0.0.0.tgz#f35eea7d705e933baf13b2f03b3f83d921403b3e" - integrity sha512-zpqiCT8bODLu3QSmLLic8xJnYWBFjOSu/fBCm189oAiTtPq/PSanNACKZDS7kgSyCJY7P+IcODzlIogBK/9RBg== - delay@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" @@ -9350,7 +9054,7 @@ docker-compose@0.24.0: dependencies: yaml "^1.10.2" -docker-compose@^0.23.5, docker-compose@^0.23.6: +docker-compose@^0.23.5: version "0.23.19" resolved "https://registry.yarnpkg.com/docker-compose/-/docker-compose-0.23.19.tgz#9947726e2fe67bdfa9e8efe1ff15aa0de2e10eb8" integrity sha512-v5vNLIdUqwj4my80wxFDkNH+4S85zsRuH29SO7dCWVWPCMt/ohZBsGN6g6KXWifT0pzQ7uOxqEKCYCDPJ8Vz4g== @@ -9491,11 +9195,6 @@ dotenv@8.6.0, dotenv@^8.2.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== -dotenv@^16.3.1: - version "16.3.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" - integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== - dotenv@~10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" @@ -9548,24 +9247,6 @@ duplexify@^4.0.0, duplexify@^4.1.2: readable-stream "^3.1.1" stream-shift "^1.0.0" -dynalite@^3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/dynalite/-/dynalite-3.2.2.tgz#34b4f4dd69638f17c0f7551a867959972c892441" - integrity sha512-sx9ZjTgMs/D4gHnba4rnBkw29648dHwHmywJet132KAbiq1ZyWx9W1fMd/eP9cPwTKDXyCBuTYOChE0qMDjaXQ== - dependencies: - async "^2.6.3" - big.js "^5.2.2" - buffer-crc32 "^0.2.13" - lazy "^1.0.11" - levelup "^4.4.0" - lock "^1.1.0" - memdown "^5.1.0" - minimist "^1.2.5" - once "^1.4.0" - subleveldown "^5.0.1" - optionalDependencies: - leveldown "^5.6.0" - eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -9672,7 +9353,7 @@ encodeurl@^1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -encoding-down@^6.2.0, encoding-down@^6.3.0: +encoding-down@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw== @@ -9780,11 +9461,6 @@ envinfo@7.8.1, envinfo@^7.7.3: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -err-code@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" - integrity sha512-CJAN+O0/yA1CKfRn9SXOGctSpEM7DCon/r/5r2eXFMY2zCCJBasFhcM5I+1kh3Ap11FsQCX+vGHceNPvpWKhoA== - err-code@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" @@ -9922,11 +9598,6 @@ es6-error@^4.0.1, es6-error@^4.1.1: resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== -es6-promise@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - esbuild-loader@^2.16.0: version "2.21.0" resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-2.21.0.tgz#2698a3e565b0db2bb19a3dd91c2b6c9aad526c80" @@ -10525,13 +10196,6 @@ fast-xml-parser@4.2.5: dependencies: strnum "^1.0.5" -fast-xml-parser@^4.1.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.3.3.tgz#aeaf5778392329f17168c40c51bcbfec8ff965be" - integrity sha512-coV/D1MhrShMvU6D0I+VAK3umz6hUaxxhL0yp/9RjfiYUfAv14rDhGQL+PLForhMdr0wq3PiV07WtkkNjJjNHg== - dependencies: - strnum "^1.0.5" - fast-xml-parser@^4.2.2, fast-xml-parser@^4.2.5: version "4.3.2" resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.3.2.tgz#761e641260706d6e13251c4ef8e3f5694d4b0d79" @@ -10872,11 +10536,6 @@ formidable@^2.1.2: once "^1.4.0" qs "^6.11.0" -fp-ts@^2.5.1: - version "2.16.2" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.16.2.tgz#7faa90f6fc2e8cf84c711d2c4e606afe2be9e342" - integrity sha512-CkqAjnIKFqvo3sCyoBTqgJvF+bHrSik584S9nhTjtBESLx26cbtVMR/T9a6ApChOcSDAaM3JydDmWDUn4EEXng== - fresh@^0.5.2, fresh@~0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -10918,7 +10577,7 @@ fs-extra@^11.1.0, fs-extra@^11.1.1: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: +fs-extra@^9.0.0, fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -10967,7 +10626,7 @@ function.prototype.name@^1.1.6: es-abstract "^1.22.1" functions-have-names "^1.2.3" -functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: +functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= @@ -11561,23 +11220,6 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -got@^11.5.1, got@^11.8.5, got@^11.8.6: - version "11.8.6" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" - integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - got@^8.3.1: version "8.3.2" resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" @@ -11618,15 +11260,6 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -gotql@^2.1.0-alpha1: - version "2.1.0-alpha1" - resolved "https://registry.yarnpkg.com/gotql/-/gotql-2.1.0-alpha1.tgz#b04e9adb0d1751a0c2de05bd4399f5c57aec79ba" - integrity sha512-4xG1AczSpK+tdKUDM4kB1ah/2LoNlmFU5IhGNktuYNBLgyWB5iDs4OE36NE7k59iTKYi2B7vudQz2Itw1ZXrRg== - dependencies: - debug "^4.1.1" - got "^11.5.1" - prepend-http "^3.0.1" - graceful-fs@4.2.11, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" @@ -11991,14 +11624,6 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -12118,11 +11743,6 @@ immediate@~3.0.5: resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== -immediate@~3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" - integrity sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg== - import-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-3.0.0.tgz#20845547718015126ea9b3676b7592fb8bd4cf92" @@ -13048,15 +12668,6 @@ jest-docblock@^29.7.0: dependencies: detect-newline "^3.0.0" -jest-dynalite@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/jest-dynalite/-/jest-dynalite-3.6.1.tgz#8bae305a3c33d9a8036f563827b173b54a323ca5" - integrity sha512-MERtTt8Pj39vFmbItMC3YuIaqLf1kh/pJIE0DRcjeP/2Fa8Nni9IxwN6XWIMgXNbFKtlOM6ppH+Bsy0rWIdPiw== - dependencies: - "@aws/dynamodb-auto-marshaller" "^0.7.1" - dynalite "^3.2.1" - setimmediate "^1.0.5" - jest-each@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" @@ -13576,11 +13187,6 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -13749,13 +13355,6 @@ keyv@^3.0.0: dependencies: json-buffer "3.0.0" -keyv@^4.0.0: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== - dependencies: - json-buffer "3.0.1" - kill-port@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/kill-port/-/kill-port-1.6.1.tgz#560fe79484583bdf3a5e908557dae614447618aa" @@ -13871,7 +13470,7 @@ koa-mount@^4.0.0: debug "^4.0.1" koa-compose "^4.1.0" -koa-passport@4.1.4, koa-passport@^4.1.4: +koa-passport@4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/koa-passport/-/koa-passport-4.1.4.tgz#5f1665c1c2a37ace79af9f970b770885ca30ccfa" integrity sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg== @@ -13905,7 +13504,7 @@ koa-send@5.0.1, koa-send@^5.0.0: http-errors "^1.7.3" resolve-path "^1.4.0" -koa-session@5.13.1, koa-session@^5.12.0: +koa-session@5.13.1: version "5.13.1" resolved "https://registry.yarnpkg.com/koa-session/-/koa-session-5.13.1.tgz#a47e39015a4b464e21e3e1e2deeca48eb83916ee" integrity sha512-TfYiun6xiFosyfIJKnEw0aoG5XmLIwM+K3OVWfkz84qY0NP2gbk0F/olRn0/Hrxq0f14s8amHVXeWyKYH3Cx3Q== @@ -13923,7 +13522,7 @@ koa-static@5.0.0, koa-static@^5.0.0: debug "^3.1.0" koa-send "^5.0.0" -koa-useragent@4.1.0, koa-useragent@^4.1.0: +koa-useragent@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/koa-useragent/-/koa-useragent-4.1.0.tgz#d3f128b552c6da3e5e9e9e9c887b2922b16e4468" integrity sha512-x/HUDZ1zAmNNh5hA9hHbPm9p3UVg2prlpHzxCXQCzbibrNS0kmj7MkCResCbAbG7ZT6FVxNSMjR94ZGamdMwxA== @@ -14023,11 +13622,6 @@ latest-version@^5.1.0: dependencies: package-json "^6.3.0" -lazy@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/lazy/-/lazy-1.0.11.tgz#daa068206282542c088288e975c297c1ae77b690" - integrity sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA== - lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -14213,13 +13807,6 @@ level-js@^5.0.0: inherits "^2.0.3" ltgt "^2.1.2" -level-option-wrap@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/level-option-wrap/-/level-option-wrap-1.1.0.tgz#ad20e68d9f3c22c8897531cc6aa7af596b1ed129" - integrity sha512-gQouC22iCqHuBLNl4BHxEZUxLvUKALAtT/Q0c6ziOxZQ8c02G/gyxHWNbLbxUzRNfMrRnbt6TZT3gNe8VBqQeg== - dependencies: - defined "~0.0.0" - level-packager@^5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939" @@ -14268,7 +13855,7 @@ level@6.0.1: level-packager "^5.1.0" leveldown "^5.4.0" -leveldown@5.6.0, leveldown@^5.4.0, leveldown@^5.6.0: +leveldown@5.6.0, leveldown@^5.4.0: version "5.6.0" resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-5.6.0.tgz#16ba937bb2991c6094e13ac5a6898ee66d3eee98" integrity sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ== @@ -14277,7 +13864,7 @@ leveldown@5.6.0, leveldown@^5.4.0, leveldown@^5.6.0: napi-macros "~2.0.0" node-gyp-build "~4.1.0" -levelup@4.4.0, levelup@^4.3.2, levelup@^4.4.0: +levelup@4.4.0, levelup@^4.3.2: version "4.4.0" resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6" integrity sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ== @@ -14466,11 +14053,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lock@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/lock/-/lock-1.1.0.tgz#53157499d1653b136ca66451071fca615703fa55" - integrity sha512-NZQIJJL5Rb9lMJ0Yl1JoVr9GSdo4HTPsUEWsSFzB8dE8DSoiLCVavWZPi7Rnlv/o73u6I24S/XYc/NmG4l8EKA== - lodash-es@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" @@ -14611,7 +14193,7 @@ lodash.xor@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.xor/-/lodash.xor-4.5.0.tgz#4d48ed7e98095b0632582ba714d3ff8ae8fb1db6" integrity sha512-sVN2zimthq7aZ5sPGXnSz32rZPuqcparVW50chJQe+mzTYV+IsxSsl/2gnkWWE2Of7K3myBQBqtLKOUEHJKRsQ== -lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.7.0: +lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -14965,18 +14547,6 @@ memdown@1.4.1: ltgt "~2.2.0" safe-buffer "~5.1.1" -memdown@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-5.1.0.tgz#608e91a9f10f37f5b5fe767667a8674129a833cb" - integrity sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw== - dependencies: - abstract-leveldown "~6.2.1" - functional-red-black-tree "~1.0.1" - immediate "~3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.2.0" - memory-pager@^1.0.2: version "1.5.0" resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" @@ -15085,11 +14655,6 @@ mimic-response@^1.0.0, mimic-response@^1.0.1: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" @@ -15533,11 +15098,6 @@ neo-async@^2.6.0, neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -neon-env@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/neon-env/-/neon-env-0.1.3.tgz#071e86fde3c698e9314f057d209e0b79ddab16e9" - integrity sha512-Zo+L6Nm19gJrjyfhxn/ZDm8eIIDzr75o64ZhijBau4LNuhLzjEAteRg3gchIvgaN8XTo5BxN6iTNP5clZQ0agA== - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -16255,23 +15815,6 @@ opentracing@>=0.12.1: resolved "https://registry.yarnpkg.com/opentracing/-/opentracing-0.14.7.tgz#25d472bd0296dc0b64d7b94cbc995219031428f5" integrity sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q== -operate-api-client@1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/operate-api-client/-/operate-api-client-1.2.3.tgz#c884ab09fe07360ac5ce5b58ae470ba1e91db879" - integrity sha512-8FWfDsHVxgYIBe4p4fB6e7SSiYdW/PPTCCLFcGnbqdUxlhcUq9ncYu6ZMMm6E3A3WKxagdInYQbxOhtTeVGhVQ== - dependencies: - camunda-saas-oauth "^1.2.0" - got "^11.8.5" - -optimize-api-client@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/optimize-api-client/-/optimize-api-client-1.0.4.tgz#a2e653780fd1e9e54a38912418b0ea27bd0484ef" - integrity sha512-2XBW+sv6eENOCHMc5v0XmH2DaaSETAb/qH5BsfpTDD8Pmeu10ZR61W7Pc/rBqauy96vPP/MfgmMphx5CjHb2xg== - dependencies: - camunda-8-credentials-from-env "^1.1.1" - camunda-saas-oauth "^1.2.4" - got "^11.8.5" - optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -16345,11 +15888,6 @@ p-cancelable@^1.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== - p-defer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" @@ -16662,7 +16200,7 @@ passport-google-oauth20@2.x.x: dependencies: passport-oauth2 "1.x.x" -passport-google-oauth@2.0.0, passport-google-oauth@^2.0.0: +passport-google-oauth@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/passport-google-oauth/-/passport-google-oauth-2.0.0.tgz#f6eb4bc96dd6c16ec0ecfdf4e05ec48ca54d4dae" integrity sha512-JKxZpBx6wBQXX1/a1s7VmdBgwOugohH+IxCy84aPTZNq/iIPX6u7Mqov1zY7MKRz3niFPol0KJz8zPLBoHKtYA== @@ -16677,14 +16215,6 @@ passport-local@1.0.0: dependencies: passport-strategy "1.x.x" -passport-microsoft@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/passport-microsoft/-/passport-microsoft-1.0.0.tgz#78954cf3201fdce61beeb6587a3b158f8e9db86c" - integrity sha512-L1JHeCbSObSZZXiG7jU2KoKie6nzZLwGt38HXz1GasKrsCQdOnf5kH8ltV4BWNUfBL2Pt1csWn1iuBSerprrcg== - dependencies: - passport-oauth2 "1.6.1" - pkginfo "0.4.x" - passport-oauth1@1.x.x: version "1.3.0" resolved "https://registry.yarnpkg.com/passport-oauth1/-/passport-oauth1-1.3.0.tgz#5d57f1415c8e28e46b461a12ec1b492934f7c354" @@ -16699,17 +16229,6 @@ passport-oauth2-refresh@^2.1.0: resolved "https://registry.yarnpkg.com/passport-oauth2-refresh/-/passport-oauth2-refresh-2.1.0.tgz#c31cd133826383f5539d16ad8ab4f35ca73ce4a4" integrity sha512-4ML7ooCESCqiTgdDBzNUFTBcPR8zQq9iM6eppEUGMMvLdsjqRL93jKwWm4Az3OJcI+Q2eIVyI8sVRcPFvxcF/A== -passport-oauth2@1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.6.1.tgz#c5aee8f849ce8bd436c7f81d904a3cd1666f181b" - integrity sha512-ZbV43Hq9d/SBSYQ22GOiglFsjsD1YY/qdiptA+8ej+9C1dL1TVB+mBE5kDH/D4AJo50+2i8f4bx0vg4/yDDZCQ== - dependencies: - base64url "3.x.x" - oauth "0.9.x" - passport-strategy "1.x.x" - uid2 "0.0.x" - utils-merge "1.x.x" - passport-oauth2@1.x.x: version "1.7.0" resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.7.0.tgz#5c4766c8531ac45ffe9ec2c09de9809e2c841fc4" @@ -17086,11 +16605,6 @@ pkg-types@^1.0.3: mlly "^1.2.0" pathe "^1.1.0" -pkginfo@0.4.x: - version "0.4.1" - resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" - integrity sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ== - pluralize@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" @@ -17420,13 +16934,6 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" -posthog-js@^1.13.4: - version "1.100.0" - resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.100.0.tgz#687b9a6e4ed226aa6572f4040b418ea0c8b3d353" - integrity sha512-r2XZEiHQ9mBK7D1G9k57I8uYZ2kZTAJ0OCX6K/OOdCWN8jKPhw3h5F9No5weilP6eVAn+hrsy7NvPV7SCX7gMg== - dependencies: - fflate "^0.4.1" - posthog-js@^1.36.0: version "1.96.1" resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.96.1.tgz#4f9719a24e4e14037b0e72d430194d7cdb576447" @@ -17723,11 +17230,6 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== -prepend-http@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-3.0.1.tgz#3e724d58fd5867465b300bb9615009fa2f8ee3b6" - integrity sha512-BLxfZh+m6UiAiCPZFJ4+vYoL7NrRs5XgCTRrjseATAggXhdZKKxn+JUNmuVYWY23bDHgaEHodxw8mnmtVEDtHw== - prettier-plugin-svelte@^2.3.0: version "2.6.0" resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.6.0.tgz#0e845b560b55cd1d951d6c50431b4949f8591746" @@ -17827,14 +17329,6 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== -promise-retry@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" - integrity sha512-StEy2osPr28o17bIW776GtwO6+Q+M9zPiZkYfosciUUMYqjhU/ffwRAH0zN2+uvGyUsn8/YICIHRzLbPacpZGw== - dependencies: - err-code "^1.0.0" - retry "^0.10.0" - promise-retry@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" @@ -18026,7 +17520,7 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== -qs@^6.10.3, qs@^6.11.0, qs@^6.4.0: +qs@^6.11.0, qs@^6.4.0: version "6.11.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== @@ -18082,11 +17576,6 @@ quick-lru@^4.0.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - quote-unquote@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/quote-unquote/-/quote-unquote-1.0.0.tgz#67a9a77148effeaf81a4d428404a710baaac8a0b" @@ -18139,11 +17628,6 @@ rc@1.2.8, rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -reachdown@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/reachdown/-/reachdown-1.1.0.tgz#c3b85b459dbd0fe2c79782233a0a38e66a9b5454" - integrity sha512-6LsdRe4cZyOjw4NnvbhUd/rGG7WQ9HMopPr+kyL018Uci4kijtxcGR5kVb5Ln13k4PEE+fEFQbjfOvNw7cnXmA== - react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" @@ -18541,11 +18025,6 @@ requizzle@^0.2.3: dependencies: lodash "^4.17.21" -resolve-alpn@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" - integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== - resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -18605,13 +18084,6 @@ responselike@1.0.2, responselike@^1.0.2: dependencies: lowercase-keys "^1.0.0" -responselike@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" - integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== - dependencies: - lowercase-keys "^2.0.0" - restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" @@ -18633,11 +18105,6 @@ retry@0.13.1, retry@^0.13.1: resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" integrity "sha1-GFsVh6z2eRnWOzVzSeA1N7JIRlg= sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" -retry@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" - integrity sha512-ZXUSQYTHdl3uS7IuCehYfMzKyIDBNoAuUblvy5oGO5UJSUTmStUUVPXbA9Qxd173Bgre53yCQczQuHgRWAdvJQ== - retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -19094,7 +18561,7 @@ serialize-javascript@^6.0.1: dependencies: randombytes "^2.1.0" -server-destroy@1.0.1, server-destroy@^1.0.1: +server-destroy@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/server-destroy/-/server-destroy-1.0.1.tgz#f13bf928e42b9c3e79383e61cc3998b5d14e6cdd" integrity sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ== @@ -19123,11 +18590,6 @@ set-function-name@^2.0.0, set-function-name@^2.0.1: functions-have-names "^1.2.3" has-property-descriptors "^1.0.0" -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" @@ -19603,7 +19065,7 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== -stack-trace@0.0.10, stack-trace@0.0.x: +stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== @@ -19885,14 +19347,6 @@ strip-outer@^1.0.0: dependencies: escape-string-regexp "^1.0.2" -stripe@9.16.0: - version "9.16.0" - resolved "https://registry.yarnpkg.com/stripe/-/stripe-9.16.0.tgz#94c24549c91fced457b9e3259e8a1a1bdb6dbd0e" - integrity sha512-Dn8K+jSoQcXjxCobRI4HXUdHjOXsiF/KszK49fJnkbeCFjZ3EZxLG2JiM/CX+Hcq27NBDtv/Sxhvy+HhTmvyaQ== - dependencies: - "@types/node" ">=8.1.0" - qs "^6.10.3" - striptags@^3.1.1: version "3.2.0" resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.2.0.tgz#cc74a137db2de8b0b9a370006334161f7dd67052" @@ -19966,18 +19420,6 @@ sublevel-pouchdb@7.2.2: ltgt "2.2.1" readable-stream "1.1.14" -subleveldown@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/subleveldown/-/subleveldown-5.0.1.tgz#aa2b4e4698a48d9a86856b2c4df1b6bce2d2ce53" - integrity sha512-cVqd/URpp7si1HWu5YqQ3vqQkjuolAwHypY1B4itPlS71/lsf6TQPZ2Y0ijT22EYVkvH5ove9JFJf4u7VGPuZw== - dependencies: - abstract-leveldown "^6.3.0" - encoding-down "^6.2.0" - inherits "^2.0.3" - level-option-wrap "^1.1.0" - levelup "^4.4.0" - reachdown "^1.1.0" - superagent@^8.0.5: version "8.1.2" resolved "https://registry.yarnpkg.com/superagent/-/superagent-8.1.2.tgz#03cb7da3ec8b32472c9d20f6c2a57c7f3765f30b" @@ -20844,11 +20286,6 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -typed-duration@^1.0.12: - version "1.0.13" - resolved "https://registry.yarnpkg.com/typed-duration/-/typed-duration-1.0.13.tgz#a40f9ba563b6e20674cac491e15ecbf6811d85a7" - integrity sha512-HLwA+hNq/2eXe03isJSfa7YJt6NikplBGdNKvlhyuR6WL5iZi2uXJIZv1SSOMEIukCZbeQ8QwIcQ801S0/Qulw== - typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -21062,7 +20499,7 @@ update-browserslist-db@^1.0.10: escalade "^3.1.1" picocolors "^1.0.0" -update-dotenv@1.1.1, update-dotenv@^1.1.1: +update-dotenv@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/update-dotenv/-/update-dotenv-1.1.1.tgz#17146f302f216c3c92419d5a327a45be910050ca" integrity sha512-3cIC18In/t0X/yH793c00qqxcKD8jVCgNOPif/fGQkFpYMGecM9YAc+kaAKXuZsM2dE9I9wFI7KvAuNX22SGMQ== @@ -21106,7 +20543,7 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -url-parse@^1.4.3, url-parse@^1.5.3: +url-parse@^1.5.3: version "1.5.10" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== @@ -21176,11 +20613,6 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" - integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== - uuid@^9.0.0, uuid@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" @@ -22079,23 +21511,3 @@ z-schema@^5.0.1: validator "^13.7.0" optionalDependencies: commander "^9.4.1" - -zeebe-node@^8.2.5: - version "8.3.1" - resolved "https://registry.yarnpkg.com/zeebe-node/-/zeebe-node-8.3.1.tgz#e100bf3708464e305305b4efa1ffde53f9786c45" - integrity sha512-68ascWO3g7g+9WwDzvfa3I9TkLKHku5auEgSINP+k5ktNfsfGW68ELDmEJA+XHZgzvGsdGILZqGRzVd5SC8aaQ== - dependencies: - "@grpc/grpc-js" "1.9.7" - "@grpc/proto-loader" "0.7.10" - chalk "^2.4.2" - console-stamp "^3.0.2" - dayjs "^1.8.15" - debug "^4.2.0" - fast-xml-parser "^4.1.3" - fp-ts "^2.5.1" - got "^11.8.5" - long "^4.0.0" - promise-retry "^1.1.1" - stack-trace "0.0.10" - typed-duration "^1.0.12" - uuid "^7.0.3" From 6964e2d146de1a51eb55ffbf8a40052bce090575 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 29 Jan 2024 13:43:51 +0000 Subject: [PATCH 009/213] Fixing update aliasing. --- .../server/scripts/integrations/postgres/reset.sh | 1 + packages/server/src/integrations/base/sql.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/server/scripts/integrations/postgres/reset.sh b/packages/server/scripts/integrations/postgres/reset.sh index 32778bd11f..29a5db0181 100755 --- a/packages/server/scripts/integrations/postgres/reset.sh +++ b/packages/server/scripts/integrations/postgres/reset.sh @@ -1,3 +1,4 @@ #!/bin/bash docker-compose down docker volume prune -f +docker volume rm postgres_pg_data diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index 3375e175e6..d33c077ee5 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -424,7 +424,7 @@ class InternalBuilder { knexWithAlias( knex: Knex, endpoint: { entityId: string; alias?: string; schema?: string } - ): { query: KnexQuery; name: string } { + ): { query: KnexQuery; aliased: string } { const tableName = endpoint.entityId const alias = endpoint.alias const aliased = alias ? alias : tableName @@ -433,7 +433,7 @@ class InternalBuilder { if (endpoint.schema) { query = query.withSchema(endpoint.schema) } - return { query, name: aliased } + return { query, aliased } } create(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { @@ -493,7 +493,7 @@ class InternalBuilder { } // start building the query - let { query, name: aliased } = this.knexWithAlias(knex, endpoint) + let { query, aliased } = this.knexWithAlias(knex, endpoint) query = query.limit(foundLimit) if (foundOffset) { query = query.offset(foundOffset) @@ -522,9 +522,9 @@ class InternalBuilder { update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { const { endpoint, body, filters } = json - let { query } = this.knexWithAlias(knex, endpoint) + let { query, aliased } = this.knexWithAlias(knex, endpoint) const parsedBody = parseBody(body) - query = this.addFilters(query, filters, { tableName: endpoint.entityId }) + query = this.addFilters(query, filters, { tableName: aliased }) // mysql can't use returning if (opts.disableReturning) { return query.update(parsedBody) @@ -535,7 +535,7 @@ class InternalBuilder { delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { const { endpoint, filters } = json - let { query, name: aliased } = this.knexWithAlias(knex, endpoint) + let { query, aliased } = this.knexWithAlias(knex, endpoint) query = this.addFilters(query, filters, { tableName: aliased }) // mysql can't use returning if (opts.disableReturning) { From 5d2ba68fae4b39086686c41999b903c05c352ba4 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 30 Jan 2024 13:35:45 +0000 Subject: [PATCH 010/213] Adding test case based on capture of real failing query. --- .../server/src/integrations/tests/sql.spec.ts | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/packages/server/src/integrations/tests/sql.spec.ts b/packages/server/src/integrations/tests/sql.spec.ts index 5cc4849d03..580a8117cb 100644 --- a/packages/server/src/integrations/tests/sql.spec.ts +++ b/packages/server/src/integrations/tests/sql.spec.ts @@ -683,3 +683,110 @@ describe("SQL query builder", () => { }) }) }) + +describe("Captures of real examples", () => { + const limit = 5000 + + it("should handle filtering by relationship", () => { + const queryJson = { + endpoint: { + datasourceId: "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + entityId: "products", + operation: "READ", + alias: "a", + }, + resource: { + fields: [ + "a.productname", + "a.productid", + "b.executorid", + "b.taskname", + "b.taskid", + "b.completed", + "b.qaid", + ], + }, + filters: { + equal: { + "1:tasks.taskname": "assembling", + }, + onEmptyFilter: "all", + }, + sort: { + productname: { + direction: "ASCENDING", + }, + }, + paginate: { + limit: 100, + page: 1, + }, + relationships: [ + { + tableName: "tasks", + column: "tasks", + through: "products_tasks", + from: "productid", + to: "taskid", + fromPrimary: "productid", + toPrimary: "taskid", + aliases: { + products_tasks: "c", + tasks: "b", + products: "a", + }, + }, + ], + meta: { + table: { + type: "table", + _id: "datasource_plus_8066e56456784eb2a00129d31be5c3e7__products", + primary: ["productid"], + name: "a", + schema: { + productname: { + type: "string", + externalType: "character varying", + autocolumn: false, + name: "productname", + constraints: { + presence: false, + }, + }, + productid: { + type: "number", + externalType: "integer", + autocolumn: true, + name: "productid", + constraints: { + presence: false, + }, + }, + tasks: { + tableId: + "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + name: "tasks", + relationshipType: "many-to-many", + fieldName: "taskid", + through: + "datasource_plus_8066e56456784eb2a00129d31be5c3e7__products_tasks", + throughFrom: "taskid", + throughTo: "productid", + type: "link", + main: true, + _id: "ca6862d9ba09146dd8a68e3b5b7055a09", + }, + }, + sourceId: "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + sourceType: "external", + primaryDisplay: "productname", + }, + }, + } + let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) + expect(query).toEqual({ + bindings: [100, "assembling", limit], + sql: `select "a"."productname" as "a.productname", "a"."productid" as "a.productid", "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", "b"."completed" as "b.completed", "b"."qaid" as "b.qaid" from (select * from "products" as "a" order by "a"."productname" asc limit $1) as "a" left join "products_tasks" as "c" on "a"."productid" = "c"."productid" left join "tasks" as "b" on "b"."taskid" = "c"."taskid" where "b"."taskname" = $2 order by "a"."productname" asc limit $3`, + }) + }) +}) From 09a0d00aa7df535454cb3eafe49714dcd1adf3e9 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 30 Jan 2024 13:50:36 +0000 Subject: [PATCH 011/213] Fixing some test cases. --- packages/server/src/integrations/tests/sql.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/server/src/integrations/tests/sql.spec.ts b/packages/server/src/integrations/tests/sql.spec.ts index 580a8117cb..bca0cf5422 100644 --- a/packages/server/src/integrations/tests/sql.spec.ts +++ b/packages/server/src/integrations/tests/sql.spec.ts @@ -502,7 +502,7 @@ describe("SQL query builder", () => { const query = sql._query(generateRelationshipJson({ schema: "production" })) expect(query).toEqual({ bindings: [500, 5000], - sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "production"."brands" limit $1) as "brands" left join "production"."products" on "brands"."brand_id" = "products"."brand_id" limit $2`, + sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "production"."brands" limit $1) as "brands" left join "production"."products" as "products" on "brands"."brand_id" = "products"."brand_id" limit $2`, }) }) @@ -510,7 +510,7 @@ describe("SQL query builder", () => { const query = sql._query(generateRelationshipJson()) expect(query).toEqual({ bindings: [500, 5000], - sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "brands" limit $1) as "brands" left join "products" on "brands"."brand_id" = "products"."brand_id" limit $2`, + sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "brands" limit $1) as "brands" left join "products" as "products" on "brands"."brand_id" = "products"."brand_id" limit $2`, }) }) @@ -520,7 +520,7 @@ describe("SQL query builder", () => { ) expect(query).toEqual({ bindings: [500, 5000], - sql: `select "stores"."store_id" as "stores.store_id", "stores"."store_name" as "stores.store_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name" from (select * from "production"."stores" limit $1) as "stores" left join "production"."stocks" on "stores"."store_id" = "stocks"."store_id" left join "production"."products" on "products"."product_id" = "stocks"."product_id" limit $2`, + sql: `select "stores"."store_id" as "stores.store_id", "stores"."store_name" as "stores.store_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name" from (select * from "production"."stores" limit $1) as "stores" left join "production"."stocks" as "stocks" on "stores"."store_id" = "stocks"."store_id" left join "production"."products" as "products" on "products"."product_id" = "stocks"."product_id" limit $2`, }) }) From bb0b776684e29a529ac5198451472e8981cadd1f Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 30 Jan 2024 17:57:10 +0000 Subject: [PATCH 012/213] Updating how aliasing is handled. --- .../server/src/api/controllers/row/alias.ts | 2 +- packages/server/src/integrations/base/sql.ts | 86 ++++++++------ .../server/src/integrations/tests/sql.spec.ts | 110 ++---------------- .../sqlQueryJson/filterByRelationship.json | 94 +++++++++++++++ packages/types/src/sdk/search.ts | 3 +- 5 files changed, 158 insertions(+), 137 deletions(-) create mode 100644 packages/server/src/integrations/tests/sqlQueryJson/filterByRelationship.json diff --git a/packages/server/src/api/controllers/row/alias.ts b/packages/server/src/api/controllers/row/alias.ts index fc00b505c4..589431cc1a 100644 --- a/packages/server/src/api/controllers/row/alias.ts +++ b/packages/server/src/api/controllers/row/alias.ts @@ -113,7 +113,7 @@ export default class AliasTables { } json.meta.tables = aliasedTables } - json.endpoint.alias = this.getAlias(json.endpoint.entityId) + json.tableAliases = this.tableAliases const response = await getDatasourceAndQuery(json) return this.reverse(response) } diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index d33c077ee5..c9be2e1ae6 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -129,8 +129,13 @@ class InternalBuilder { addFilters( query: KnexQuery, filters: SearchFilters | undefined, - opts: { relationship?: boolean; tableName?: string } + tableName: string, + opts: { aliases?: Record; relationship?: boolean } ): KnexQuery { + function getTableName(name: string) { + const alias = opts.aliases?.[name] + return alias || name + } function iterate( structure: { [key: string]: any }, fn: (key: string, value: any) => void @@ -139,10 +144,11 @@ class InternalBuilder { const updatedKey = dbCore.removeKeyNumbering(key) const isRelationshipField = updatedKey.includes(".") if (!opts.relationship && !isRelationshipField) { - fn(`${opts.tableName}.${updatedKey}`, value) + fn(`${getTableName(tableName)}.${updatedKey}`, value) } if (opts.relationship && isRelationshipField) { - fn(updatedKey, value) + const [filterTableName, property] = updatedKey.split(".") + fn(`${getTableName(filterTableName)}.${property}`, value) } } } @@ -345,17 +351,15 @@ class InternalBuilder { query: KnexQuery, fromTable: string, relationships: RelationshipsJson[] | undefined, - schema: string | undefined + schema: string | undefined, + aliases?: Record ): KnexQuery { if (!relationships) { return query } const tableSets: Record = {} - // add up all aliases - let aliases: Record = {} // aggregate into table sets (all the same to tables) for (let relationship of relationships) { - aliases = { ...aliases, ...relationship.aliases } const keyObj: { toTable: string; throughTable: string | undefined } = { toTable: relationship.tableName, throughTable: undefined, @@ -372,9 +376,9 @@ class InternalBuilder { } for (let [key, relationships] of Object.entries(tableSets)) { const { toTable, throughTable } = JSON.parse(key) - const toAlias = aliases[toTable] || toTable, - throughAlias = aliases[throughTable] || throughTable, - fromAlias = aliases[fromTable] || fromTable + const toAlias = aliases?.[toTable] || toTable, + throughAlias = aliases?.[throughTable] || throughTable, + fromAlias = aliases?.[fromTable] || fromTable let toTableWithSchema = this.tableNameWithSchema(toTable, { alias: toAlias, schema, @@ -423,22 +427,23 @@ class InternalBuilder { knexWithAlias( knex: Knex, - endpoint: { entityId: string; alias?: string; schema?: string } - ): { query: KnexQuery; aliased: string } { + endpoint: QueryJson["endpoint"], + aliases?: QueryJson["tableAliases"] + ): KnexQuery { const tableName = endpoint.entityId - const alias = endpoint.alias - const aliased = alias ? alias : tableName - const tableAliased = alias ? `${tableName} as ${alias}` : tableName + const tableAliased = aliases?.[tableName] + ? `${tableName} as ${aliases?.[tableName]}` + : tableName let query = knex(tableAliased) if (endpoint.schema) { query = query.withSchema(endpoint.schema) } - return { query, aliased } + return query } create(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { const { endpoint, body } = json - let { query } = this.knexWithAlias(knex, endpoint) + let query = this.knexWithAlias(knex, endpoint) const parsedBody = parseBody(body) // make sure no null values in body for creation for (let [key, value] of Object.entries(parsedBody)) { @@ -457,7 +462,7 @@ class InternalBuilder { bulkCreate(knex: Knex, json: QueryJson): KnexQuery { const { endpoint, body } = json - let { query } = this.knexWithAlias(knex, endpoint) + let query = this.knexWithAlias(knex, endpoint) if (!Array.isArray(body)) { return query } @@ -466,8 +471,10 @@ class InternalBuilder { } read(knex: Knex, json: QueryJson, limit: number): KnexQuery { - let { endpoint, resource, filters, paginate, relationships } = json + let { endpoint, resource, filters, paginate, relationships, tableAliases } = + json + const tableName = endpoint.entityId // select all if not specified if (!resource) { resource = { fields: [] } @@ -493,19 +500,20 @@ class InternalBuilder { } // start building the query - let { query, aliased } = this.knexWithAlias(knex, endpoint) + let query = this.knexWithAlias(knex, endpoint, tableAliases) query = query.limit(foundLimit) if (foundOffset) { query = query.offset(foundOffset) } - query = this.addFilters(query, filters, { tableName: aliased }) + query = this.addFilters(query, filters, tableName, { + aliases: tableAliases, + }) // add sorting to pre-query query = this.addSorting(query, json) - // @ts-ignore - let preQuery: KnexQuery = knex({ - // @ts-ignore - [aliased]: query, - }).select(selectStatement) + const alias = tableAliases?.[tableName] || tableName + let preQuery = knex({ + [alias]: query, + } as any).select(selectStatement) as any // have to add after as well (this breaks MS-SQL) if (this.client !== SqlClient.MS_SQL) { preQuery = this.addSorting(preQuery, json) @@ -513,18 +521,24 @@ class InternalBuilder { // handle joins query = this.addRelationships( preQuery, - aliased, + tableName, relationships, - endpoint.schema + endpoint.schema, + tableAliases ) - return this.addFilters(query, filters, { relationship: true }) + return this.addFilters(query, filters, tableName, { + relationship: true, + aliases: tableAliases, + }) } update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { - const { endpoint, body, filters } = json - let { query, aliased } = this.knexWithAlias(knex, endpoint) + const { endpoint, body, filters, tableAliases } = json + let query = this.knexWithAlias(knex, endpoint, tableAliases) const parsedBody = parseBody(body) - query = this.addFilters(query, filters, { tableName: aliased }) + query = this.addFilters(query, filters, endpoint.entityId, { + aliases: tableAliases, + }) // mysql can't use returning if (opts.disableReturning) { return query.update(parsedBody) @@ -534,9 +548,11 @@ class InternalBuilder { } delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery { - const { endpoint, filters } = json - let { query, aliased } = this.knexWithAlias(knex, endpoint) - query = this.addFilters(query, filters, { tableName: aliased }) + const { endpoint, filters, tableAliases } = json + let query = this.knexWithAlias(knex, endpoint, tableAliases) + query = this.addFilters(query, filters, endpoint.entityId, { + aliases: tableAliases, + }) // mysql can't use returning if (opts.disableReturning) { return query.delete() diff --git a/packages/server/src/integrations/tests/sql.spec.ts b/packages/server/src/integrations/tests/sql.spec.ts index bca0cf5422..0e7257242c 100644 --- a/packages/server/src/integrations/tests/sql.spec.ts +++ b/packages/server/src/integrations/tests/sql.spec.ts @@ -1,5 +1,7 @@ -const Sql = require("../base/sql").default -const { SqlClient } = require("../utils") +import { SqlClient } from "../utils" +import Sql from "../base/sql" +import { QueryJson } from "@budibase/types" +import { join } from "path" const TABLE_NAME = "test" @@ -17,7 +19,7 @@ function generateReadJson({ filters, sort, paginate, -}: any = {}) { +}: any = {}): QueryJson { return { endpoint: endpoint(table || TABLE_NAME, "READ"), resource: { @@ -30,7 +32,7 @@ function generateReadJson({ table: { name: table || TABLE_NAME, primary: ["id"], - }, + } as any, }, } } @@ -687,102 +689,12 @@ describe("SQL query builder", () => { describe("Captures of real examples", () => { const limit = 5000 + function getJson(name: string): QueryJson { + return require(join(__dirname, "sqlQueryJson", name)) as QueryJson + } + it("should handle filtering by relationship", () => { - const queryJson = { - endpoint: { - datasourceId: "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - entityId: "products", - operation: "READ", - alias: "a", - }, - resource: { - fields: [ - "a.productname", - "a.productid", - "b.executorid", - "b.taskname", - "b.taskid", - "b.completed", - "b.qaid", - ], - }, - filters: { - equal: { - "1:tasks.taskname": "assembling", - }, - onEmptyFilter: "all", - }, - sort: { - productname: { - direction: "ASCENDING", - }, - }, - paginate: { - limit: 100, - page: 1, - }, - relationships: [ - { - tableName: "tasks", - column: "tasks", - through: "products_tasks", - from: "productid", - to: "taskid", - fromPrimary: "productid", - toPrimary: "taskid", - aliases: { - products_tasks: "c", - tasks: "b", - products: "a", - }, - }, - ], - meta: { - table: { - type: "table", - _id: "datasource_plus_8066e56456784eb2a00129d31be5c3e7__products", - primary: ["productid"], - name: "a", - schema: { - productname: { - type: "string", - externalType: "character varying", - autocolumn: false, - name: "productname", - constraints: { - presence: false, - }, - }, - productid: { - type: "number", - externalType: "integer", - autocolumn: true, - name: "productid", - constraints: { - presence: false, - }, - }, - tasks: { - tableId: - "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - name: "tasks", - relationshipType: "many-to-many", - fieldName: "taskid", - through: - "datasource_plus_8066e56456784eb2a00129d31be5c3e7__products_tasks", - throughFrom: "taskid", - throughTo: "productid", - type: "link", - main: true, - _id: "ca6862d9ba09146dd8a68e3b5b7055a09", - }, - }, - sourceId: "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - sourceType: "external", - primaryDisplay: "productname", - }, - }, - } + const queryJson = getJson(`filterByRelationship.json`) let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) expect(query).toEqual({ bindings: [100, "assembling", limit], diff --git a/packages/server/src/integrations/tests/sqlQueryJson/filterByRelationship.json b/packages/server/src/integrations/tests/sqlQueryJson/filterByRelationship.json new file mode 100644 index 0000000000..eb1025f382 --- /dev/null +++ b/packages/server/src/integrations/tests/sqlQueryJson/filterByRelationship.json @@ -0,0 +1,94 @@ +{ + "endpoint": { + "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "entityId": "products", + "operation": "READ" + }, + "resource": { + "fields": [ + "a.productname", + "a.productid", + "b.executorid", + "b.taskname", + "b.taskid", + "b.completed", + "b.qaid" + ] + }, + "filters": { + "equal": { + "1:tasks.taskname": "assembling" + }, + "onEmptyFilter": "all" + }, + "sort": { + "productname": { + "direction": "ASCENDING" + } + }, + "paginate": { + "limit": 100, + "page": 1 + }, + "relationships": [ + { + "tableName": "tasks", + "column": "tasks", + "through": "products_tasks", + "from": "productid", + "to": "taskid", + "fromPrimary": "productid", + "toPrimary": "taskid" + } + ], + "tableAliases": { + "products_tasks": "c", + "tasks": "b", + "products": "a" + }, + "meta": { + "table": { + "type": "table", + "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__products", + "primary": [ + "productid" + ], + "name": "a", + "schema": { + "productname": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "productname", + "constraints": { + "presence": false + } + }, + "productid": { + "type": "number", + "externalType": "integer", + "autocolumn": true, + "name": "productid", + "constraints": { + "presence": false + } + }, + "tasks": { + "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + "name": "tasks", + "relationshipType": "many-to-many", + "fieldName": "taskid", + "through": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__products_tasks", + "throughFrom": "taskid", + "throughTo": "productid", + "type": "link", + "main": true, + "_id": "ca6862d9ba09146dd8a68e3b5b7055a09" + } + }, + "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "sourceType": "external", + "primaryDisplay": "productname" + } + } +} \ No newline at end of file diff --git a/packages/types/src/sdk/search.ts b/packages/types/src/sdk/search.ts index a4045c2558..67c344d845 100644 --- a/packages/types/src/sdk/search.ts +++ b/packages/types/src/sdk/search.ts @@ -67,7 +67,6 @@ export interface RelationshipsJson { fromPrimary?: string toPrimary?: string tableName: string - aliases?: Record column: string } @@ -75,7 +74,6 @@ export interface QueryJson { endpoint: { datasourceId: string entityId: string - alias?: string operation: Operation schema?: string } @@ -96,6 +94,7 @@ export interface QueryJson { idFilter?: SearchFilters } relationships?: RelationshipsJson[] + tableAliases?: Record } export interface SqlQuery { From 09ff8a06624c3c99ac0c5b5dfc046f6538a08a43 Mon Sep 17 00:00:00 2001 From: Mitch-Budibase Date: Wed, 31 Jan 2024 15:00:32 +0000 Subject: [PATCH 013/213] License Test Changes License.manage.spec.ts/StripeAPI.ts - Test updated and now successfully updates from Free plan to premium - createCheckoutSession updated to support this plan upgrade --- qa-core/src/account-api/api/apis/StripeAPI.ts | 4 ++-- .../tests/licensing/license.manage.spec.ts | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/qa-core/src/account-api/api/apis/StripeAPI.ts b/qa-core/src/account-api/api/apis/StripeAPI.ts index 5a4e810655..aeb027f428 100644 --- a/qa-core/src/account-api/api/apis/StripeAPI.ts +++ b/qa-core/src/account-api/api/apis/StripeAPI.ts @@ -11,12 +11,12 @@ export default class StripeAPI extends BaseAPI { } async createCheckoutSession( - priceId: string, + price: object, opts: APIRequestOpts = { status: 200 } ) { return this.doRequest(() => { return this.client.post(`/api/stripe/checkout-session`, { - body: { priceId }, + body: { prices: [price] }, }) }, opts) } diff --git a/qa-core/src/account-api/tests/licensing/license.manage.spec.ts b/qa-core/src/account-api/tests/licensing/license.manage.spec.ts index 9a8662ea3b..2d5b9332c6 100644 --- a/qa-core/src/account-api/tests/licensing/license.manage.spec.ts +++ b/qa-core/src/account-api/tests/licensing/license.manage.spec.ts @@ -36,11 +36,11 @@ describe("license management", () => { const [plansRes, planBody] = await config.api.licenses.getPlans() // Select priceId from premium plan - let premiumPriceId = null - let businessPriceId = "" + let premiumPrice = null + let businessPriceId: "" for (const plan of planBody) { if (plan.type === PlanType.PREMIUM_PLUS) { - premiumPriceId = plan.prices[0].priceId + premiumPrice = plan.prices[0] } if (plan.type === PlanType.ENTERPRISE_BASIC) { businessPriceId = plan.prices[0].priceId @@ -49,7 +49,7 @@ describe("license management", () => { // Create checkout session for price const checkoutSessionRes = await config.api.stripe.createCheckoutSession( - premiumPriceId + { id: premiumPrice.priceId, type: premiumPrice.type } ) const checkoutSessionUrl = checkoutSessionRes[1].url expect(checkoutSessionUrl).toContain("checkout.stripe.com") @@ -84,7 +84,7 @@ describe("license management", () => { customer: customer.id, items: [ { - price: premiumPriceId, + price: premiumPrice.priceId, quantity: 1, }, ], @@ -105,6 +105,7 @@ describe("license management", () => { expect(portalSessionBody.url).toContain("billing.stripe.com") // Update subscription from premium to business license + //await config.api.licenses.updatePlan(businessPriceId.priceId) await config.api.licenses.updatePlan(businessPriceId) // License updated to Business From c4f4a46d7002e3b4321bb6cd7c22b0a608d481bf Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 5 Feb 2024 12:45:19 +0000 Subject: [PATCH 014/213] Quick fix based on testing. --- .../server/src/api/controllers/row/alias.ts | 7 +++++- packages/server/src/integrations/base/sql.ts | 1 - .../server/src/integrations/tests/sql.spec.ts | 17 ------------- .../src/integrations/tests/sqlAlias.spec.ts | 25 +++++++++++++++++++ 4 files changed, 31 insertions(+), 19 deletions(-) create mode 100644 packages/server/src/integrations/tests/sqlAlias.spec.ts diff --git a/packages/server/src/api/controllers/row/alias.ts b/packages/server/src/api/controllers/row/alias.ts index 589431cc1a..6533e51728 100644 --- a/packages/server/src/api/controllers/row/alias.ts +++ b/packages/server/src/api/controllers/row/alias.ts @@ -113,7 +113,12 @@ export default class AliasTables { } json.meta.tables = aliasedTables } - json.tableAliases = this.tableAliases + // invert and return + const invertedTableAliases: Record = {} + for (let [key, value] of Object.entries(this.tableAliases)) { + invertedTableAliases[value] = key + } + json.tableAliases = invertedTableAliases const response = await getDatasourceAndQuery(json) return this.reverse(response) } diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index c9be2e1ae6..cc2e1d94a8 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -499,7 +499,6 @@ class InternalBuilder { foundLimit = paginate.limit } // start building the query - let query = this.knexWithAlias(knex, endpoint, tableAliases) query = query.limit(foundLimit) if (foundOffset) { diff --git a/packages/server/src/integrations/tests/sql.spec.ts b/packages/server/src/integrations/tests/sql.spec.ts index 0e7257242c..cf22064cb7 100644 --- a/packages/server/src/integrations/tests/sql.spec.ts +++ b/packages/server/src/integrations/tests/sql.spec.ts @@ -685,20 +685,3 @@ describe("SQL query builder", () => { }) }) }) - -describe("Captures of real examples", () => { - const limit = 5000 - - function getJson(name: string): QueryJson { - return require(join(__dirname, "sqlQueryJson", name)) as QueryJson - } - - it("should handle filtering by relationship", () => { - const queryJson = getJson(`filterByRelationship.json`) - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: [100, "assembling", limit], - sql: `select "a"."productname" as "a.productname", "a"."productid" as "a.productid", "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", "b"."completed" as "b.completed", "b"."qaid" as "b.qaid" from (select * from "products" as "a" order by "a"."productname" asc limit $1) as "a" left join "products_tasks" as "c" on "a"."productid" = "c"."productid" left join "tasks" as "b" on "b"."taskid" = "c"."taskid" where "b"."taskname" = $2 order by "a"."productname" asc limit $3`, - }) - }) -}) diff --git a/packages/server/src/integrations/tests/sqlAlias.spec.ts b/packages/server/src/integrations/tests/sqlAlias.spec.ts new file mode 100644 index 0000000000..cfd82cfd01 --- /dev/null +++ b/packages/server/src/integrations/tests/sqlAlias.spec.ts @@ -0,0 +1,25 @@ +import { QueryJson } from "@budibase/types" +import { join } from "path" +import Sql from "../base/sql" +import { SqlClient } from "../utils" + +describe("Captures of real examples", () => { + const limit = 5000 + + function getJson(name: string): QueryJson { + return require(join(__dirname, "sqlQueryJson", name)) as QueryJson + } + + it("should handle basic retrieval", () => { + const queryJson = getJson("") + }) + + it("should handle filtering by relationship", () => { + const queryJson = getJson("filterByRelationship.json") + let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) + expect(query).toEqual({ + bindings: [100, "assembling", limit], + sql: `select "a"."productname" as "a.productname", "a"."productid" as "a.productid", "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", "b"."completed" as "b.completed", "b"."qaid" as "b.qaid" from (select * from "products" as "a" order by "a"."productname" asc limit $1) as "a" left join "products_tasks" as "c" on "a"."productid" = "c"."productid" left join "tasks" as "b" on "b"."taskid" = "c"."taskid" where "b"."taskname" = $2 order by "a"."productname" asc limit $3`, + }) + }) +}) From e8e7eea47a234241dd2c79196b7e101b183c56ca Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 5 Feb 2024 15:23:24 +0000 Subject: [PATCH 015/213] Adding some test cases for aliasing. --- .../src/integrations/tests/sqlAlias.spec.ts | 65 ++++++- .../basicFetchWithRelationships.json | 183 ++++++++++++++++++ .../sqlQueryJson/createWithRelationships.json | 173 +++++++++++++++++ .../tests/sqlQueryJson/deleteSimple.json | 75 +++++++ .../sqlQueryJson/updateRelationship.json | 181 +++++++++++++++++ .../tests/sqlQueryJson/updateSimple.json | 181 +++++++++++++++++ 6 files changed, 850 insertions(+), 8 deletions(-) create mode 100644 packages/server/src/integrations/tests/sqlQueryJson/basicFetchWithRelationships.json create mode 100644 packages/server/src/integrations/tests/sqlQueryJson/createWithRelationships.json create mode 100644 packages/server/src/integrations/tests/sqlQueryJson/deleteSimple.json create mode 100644 packages/server/src/integrations/tests/sqlQueryJson/updateRelationship.json create mode 100644 packages/server/src/integrations/tests/sqlQueryJson/updateSimple.json diff --git a/packages/server/src/integrations/tests/sqlAlias.spec.ts b/packages/server/src/integrations/tests/sqlAlias.spec.ts index cfd82cfd01..c91d988849 100644 --- a/packages/server/src/integrations/tests/sqlAlias.spec.ts +++ b/packages/server/src/integrations/tests/sqlAlias.spec.ts @@ -10,16 +10,65 @@ describe("Captures of real examples", () => { return require(join(__dirname, "sqlQueryJson", name)) as QueryJson } - it("should handle basic retrieval", () => { - const queryJson = getJson("") + describe("create", () => { + it("should create a row with relationships", () => { + const queryJson = getJson("createWithRelationships.json") + let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) + expect(query).toEqual({ + bindings: ["A Street", 34, "London", "A", "B", "designer", 1990], + sql: `insert into "persons" ("address", "age", "city", "firstname", "lastname", "type", "year") values ($1, $2, $3, $4, $5, $6, $7) returning *`, + }) + }) }) - it("should handle filtering by relationship", () => { - const queryJson = getJson("filterByRelationship.json") - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: [100, "assembling", limit], - sql: `select "a"."productname" as "a.productname", "a"."productid" as "a.productid", "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", "b"."completed" as "b.completed", "b"."qaid" as "b.qaid" from (select * from "products" as "a" order by "a"."productname" asc limit $1) as "a" left join "products_tasks" as "c" on "a"."productid" = "c"."productid" left join "tasks" as "b" on "b"."taskid" = "c"."taskid" where "b"."taskname" = $2 order by "a"."productname" asc limit $3`, + describe("read", () => { + it("should handle basic retrieval with relationships", () => { + const queryJson = getJson("basicFetchWithRelationships.json") + let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) + expect(query).toEqual({ + bindings: [100, limit], + sql: `select "a"."year" as "a.year", "a"."firstname" as "a.firstname", "a"."personid" as "a.personid", "a"."address" as "a.address", "a"."age" as "a.age", "a"."type" as "a.type", "a"."city" as "a.city", "a"."lastname" as "a.lastname", "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", "b"."completed" as "b.completed", "b"."qaid" as "b.qaid", "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", "b"."completed" as "b.completed", "b"."qaid" as "b.qaid" from (select * from "persons" as "a" order by "a"."firstname" asc limit $1) as "a" left join "tasks" as "b" on "a"."personid" = "b"."qaid" or "a"."personid" = "b"."executorid" order by "a"."firstname" asc limit $2`, + }) + }) + + it("should handle filtering by relationship", () => { + const queryJson = getJson("filterByRelationship.json") + let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) + expect(query).toEqual({ + bindings: [100, "assembling", limit], + sql: `select "a"."productname" as "a.productname", "a"."productid" as "a.productid", "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", "b"."completed" as "b.completed", "b"."qaid" as "b.qaid" from (select * from "products" as "a" order by "a"."productname" asc limit $1) as "a" left join "products_tasks" as "c" on "a"."productid" = "c"."productid" left join "tasks" as "b" on "b"."taskid" = "c"."taskid" where "b"."taskname" = $2 order by "a"."productname" asc limit $3`, + }) + }) + }) + + describe("update", () => { + it("should handle performing a simple update", () => { + const queryJson = getJson("updateSimple.json") + let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) + expect(query).toEqual({ + bindings: [1990, "C", "A Street", 34, "designer", "London", "B", 5], + sql: `update "persons" as "a" set "year" = $1, "firstname" = $2, "address" = $3, "age" = $4, "type" = $5, "city" = $6, "lastname" = $7 where "a"."personid" = $8 returning *`, + }) + }) + + it("should handle performing an update of relationships", () => { + const queryJson = getJson("updateRelationship.json") + let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) + expect(query).toEqual({ + bindings: [1990, "C", "A Street", 34, "designer", "London", "B", 5], + sql: `update "persons" as "a" set "year" = $1, "firstname" = $2, "address" = $3, "age" = $4, "type" = $5, "city" = $6, "lastname" = $7 where "a"."personid" = $8 returning *`, + }) + }) + }) + + describe("delete", () => { + it("should handle deleting with relationships", () => { + const queryJson = getJson("deleteSimple.json") + let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) + expect(query).toEqual({ + bindings: ["ddd", ""], + sql: `delete from "compositetable" as "a" where "a"."keypartone" = $1 and "a"."keyparttwo" = $2 returning "a"."keyparttwo" as "a.keyparttwo", "a"."keypartone" as "a.keypartone", "a"."name" as "a.name"`, + }) }) }) }) diff --git a/packages/server/src/integrations/tests/sqlQueryJson/basicFetchWithRelationships.json b/packages/server/src/integrations/tests/sqlQueryJson/basicFetchWithRelationships.json new file mode 100644 index 0000000000..3445f5fe67 --- /dev/null +++ b/packages/server/src/integrations/tests/sqlQueryJson/basicFetchWithRelationships.json @@ -0,0 +1,183 @@ +{ + "endpoint": { + "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "entityId": "persons", + "operation": "READ" + }, + "resource": { + "fields": [ + "a.year", + "a.firstname", + "a.personid", + "a.address", + "a.age", + "a.type", + "a.city", + "a.lastname", + "b.executorid", + "b.taskname", + "b.taskid", + "b.completed", + "b.qaid", + "b.executorid", + "b.taskname", + "b.taskid", + "b.completed", + "b.qaid" + ] + }, + "filters": {}, + "sort": { + "firstname": { + "direction": "ASCENDING" + } + }, + "paginate": { + "limit": 100, + "page": 1 + }, + "relationships": [ + { + "tableName": "tasks", + "column": "QA", + "from": "personid", + "to": "qaid", + "aliases": { + "tasks": "b", + "persons": "a" + } + }, + { + "tableName": "tasks", + "column": "executor", + "from": "personid", + "to": "executorid", + "aliases": { + "tasks": "b", + "persons": "a" + } + } + ], + "extra": { + "idFilter": {} + }, + "meta": { + "table": { + "type": "table", + "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__persons", + "primary": [ + "personid" + ], + "name": "a", + "schema": { + "year": { + "type": "number", + "externalType": "integer", + "autocolumn": false, + "name": "year", + "constraints": { + "presence": false + } + }, + "firstname": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "firstname", + "constraints": { + "presence": false + } + }, + "personid": { + "type": "number", + "externalType": "integer", + "autocolumn": true, + "name": "personid", + "constraints": { + "presence": false + } + }, + "address": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "address", + "constraints": { + "presence": false + } + }, + "age": { + "type": "number", + "externalType": "integer", + "autocolumn": false, + "name": "age", + "constraints": { + "presence": false + } + }, + "type": { + "type": "options", + "externalType": "USER-DEFINED", + "autocolumn": false, + "name": "type", + "constraints": { + "presence": false, + "inclusion": [ + "support", + "designer", + "programmer", + "qa" + ] + } + }, + "city": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "city", + "constraints": { + "presence": false + } + }, + "lastname": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "lastname", + "constraints": { + "presence": false + } + }, + "QA": { + "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + "name": "QA", + "relationshipType": "many-to-one", + "fieldName": "qaid", + "type": "link", + "main": true, + "_id": "ccb68481c80c34217a4540a2c6c27fe46", + "foreignKey": "personid" + }, + "executor": { + "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + "name": "executor", + "relationshipType": "many-to-one", + "fieldName": "executorid", + "type": "link", + "main": true, + "_id": "c89530b9770d94bec851e062b5cff3001", + "foreignKey": "personid", + "tableName": "persons" + } + }, + "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "sourceType": "external", + "primaryDisplay": "firstname", + "views": {} + } + }, + "tableAliases": { + "persons": "a", + "tasks": "b" + } +} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/createWithRelationships.json b/packages/server/src/integrations/tests/sqlQueryJson/createWithRelationships.json new file mode 100644 index 0000000000..20331b949a --- /dev/null +++ b/packages/server/src/integrations/tests/sqlQueryJson/createWithRelationships.json @@ -0,0 +1,173 @@ +{ + "endpoint": { + "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "entityId": "persons", + "operation": "CREATE" + }, + "resource": { + "fields": [ + "a.year", + "a.firstname", + "a.personid", + "a.address", + "a.age", + "a.type", + "a.city", + "a.lastname" + ] + }, + "filters": {}, + "relationships": [ + { + "tableName": "tasks", + "column": "QA", + "from": "personid", + "to": "qaid", + "aliases": { + "tasks": "b", + "persons": "a" + } + }, + { + "tableName": "tasks", + "column": "executor", + "from": "personid", + "to": "executorid", + "aliases": { + "tasks": "b", + "persons": "a" + } + } + ], + "body": { + "year": 1990, + "firstname": "A", + "address": "A Street", + "age": 34, + "type": "designer", + "city": "London", + "lastname": "B" + }, + "extra": { + "idFilter": {} + }, + "meta": { + "table": { + "type": "table", + "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__persons", + "primary": [ + "personid" + ], + "name": "a", + "schema": { + "year": { + "type": "number", + "externalType": "integer", + "autocolumn": false, + "name": "year", + "constraints": { + "presence": false + } + }, + "firstname": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "firstname", + "constraints": { + "presence": false + } + }, + "personid": { + "type": "number", + "externalType": "integer", + "autocolumn": true, + "name": "personid", + "constraints": { + "presence": false + } + }, + "address": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "address", + "constraints": { + "presence": false + } + }, + "age": { + "type": "number", + "externalType": "integer", + "autocolumn": false, + "name": "age", + "constraints": { + "presence": false + } + }, + "type": { + "type": "options", + "externalType": "USER-DEFINED", + "autocolumn": false, + "name": "type", + "constraints": { + "presence": false, + "inclusion": [ + "support", + "designer", + "programmer", + "qa" + ] + } + }, + "city": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "city", + "constraints": { + "presence": false + } + }, + "lastname": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "lastname", + "constraints": { + "presence": false + } + }, + "QA": { + "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + "name": "QA", + "relationshipType": "many-to-one", + "fieldName": "qaid", + "type": "link", + "main": true, + "_id": "ccb68481c80c34217a4540a2c6c27fe46", + "foreignKey": "personid" + }, + "executor": { + "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + "name": "executor", + "relationshipType": "many-to-one", + "fieldName": "executorid", + "type": "link", + "main": true, + "_id": "c89530b9770d94bec851e062b5cff3001", + "foreignKey": "personid", + "tableName": "persons" + } + }, + "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "sourceType": "external", + "primaryDisplay": "firstname", + "views": {} + } + }, + "tableAliases": { + "persons": "a", + "tasks": "b" + } +} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/deleteSimple.json b/packages/server/src/integrations/tests/sqlQueryJson/deleteSimple.json new file mode 100644 index 0000000000..2266b8c8be --- /dev/null +++ b/packages/server/src/integrations/tests/sqlQueryJson/deleteSimple.json @@ -0,0 +1,75 @@ +{ + "endpoint": { + "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "entityId": "compositetable", + "operation": "DELETE" + }, + "resource": { + "fields": [ + "a.keyparttwo", + "a.keypartone", + "a.name" + ] + }, + "filters": { + "equal": { + "keypartone": "ddd", + "keyparttwo": "" + } + }, + "relationships": [], + "extra": { + "idFilter": { + "equal": { + "keypartone": "ddd", + "keyparttwo": "" + } + } + }, + "meta": { + "table": { + "type": "table", + "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__compositetable", + "primary": [ + "keypartone", + "keyparttwo" + ], + "name": "a", + "schema": { + "keyparttwo": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "keyparttwo", + "constraints": { + "presence": true + } + }, + "keypartone": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "keypartone", + "constraints": { + "presence": true + } + }, + "name": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "name", + "constraints": { + "presence": false + } + } + }, + "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "sourceType": "external", + "primaryDisplay": "keypartone" + } + }, + "tableAliases": { + "compositetable": "a" + } +} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/updateRelationship.json b/packages/server/src/integrations/tests/sqlQueryJson/updateRelationship.json new file mode 100644 index 0000000000..01e795bd6c --- /dev/null +++ b/packages/server/src/integrations/tests/sqlQueryJson/updateRelationship.json @@ -0,0 +1,181 @@ +{ + "endpoint": { + "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "entityId": "persons", + "operation": "UPDATE" + }, + "resource": { + "fields": [ + "a.year", + "a.firstname", + "a.personid", + "a.address", + "a.age", + "a.type", + "a.city", + "a.lastname" + ] + }, + "filters": { + "equal": { + "personid": 5 + } + }, + "relationships": [ + { + "tableName": "tasks", + "column": "QA", + "from": "personid", + "to": "qaid", + "aliases": { + "tasks": "b", + "persons": "a" + } + }, + { + "tableName": "tasks", + "column": "executor", + "from": "personid", + "to": "executorid", + "aliases": { + "tasks": "b", + "persons": "a" + } + } + ], + "body": { + "year": 1990, + "firstname": "C", + "address": "A Street", + "age": 34, + "type": "designer", + "city": "London", + "lastname": "B" + }, + "extra": { + "idFilter": { + "equal": { + "personid": 5 + } + } + }, + "meta": { + "table": { + "type": "table", + "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__persons", + "primary": [ + "personid" + ], + "name": "a", + "schema": { + "year": { + "type": "number", + "externalType": "integer", + "autocolumn": false, + "name": "year", + "constraints": { + "presence": false + } + }, + "firstname": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "firstname", + "constraints": { + "presence": false + } + }, + "personid": { + "type": "number", + "externalType": "integer", + "autocolumn": true, + "name": "personid", + "constraints": { + "presence": false + } + }, + "address": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "address", + "constraints": { + "presence": false + } + }, + "age": { + "type": "number", + "externalType": "integer", + "autocolumn": false, + "name": "age", + "constraints": { + "presence": false + } + }, + "type": { + "type": "options", + "externalType": "USER-DEFINED", + "autocolumn": false, + "name": "type", + "constraints": { + "presence": false, + "inclusion": [ + "support", + "designer", + "programmer", + "qa" + ] + } + }, + "city": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "city", + "constraints": { + "presence": false + } + }, + "lastname": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "lastname", + "constraints": { + "presence": false + } + }, + "QA": { + "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + "name": "QA", + "relationshipType": "many-to-one", + "fieldName": "qaid", + "type": "link", + "main": true, + "_id": "ccb68481c80c34217a4540a2c6c27fe46", + "foreignKey": "personid" + }, + "executor": { + "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + "name": "executor", + "relationshipType": "many-to-one", + "fieldName": "executorid", + "type": "link", + "main": true, + "_id": "c89530b9770d94bec851e062b5cff3001", + "foreignKey": "personid", + "tableName": "persons" + } + }, + "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "sourceType": "external", + "primaryDisplay": "firstname", + "views": {} + } + }, + "tableAliases": { + "persons": "a", + "tasks": "b" + } +} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/updateSimple.json b/packages/server/src/integrations/tests/sqlQueryJson/updateSimple.json new file mode 100644 index 0000000000..01e795bd6c --- /dev/null +++ b/packages/server/src/integrations/tests/sqlQueryJson/updateSimple.json @@ -0,0 +1,181 @@ +{ + "endpoint": { + "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "entityId": "persons", + "operation": "UPDATE" + }, + "resource": { + "fields": [ + "a.year", + "a.firstname", + "a.personid", + "a.address", + "a.age", + "a.type", + "a.city", + "a.lastname" + ] + }, + "filters": { + "equal": { + "personid": 5 + } + }, + "relationships": [ + { + "tableName": "tasks", + "column": "QA", + "from": "personid", + "to": "qaid", + "aliases": { + "tasks": "b", + "persons": "a" + } + }, + { + "tableName": "tasks", + "column": "executor", + "from": "personid", + "to": "executorid", + "aliases": { + "tasks": "b", + "persons": "a" + } + } + ], + "body": { + "year": 1990, + "firstname": "C", + "address": "A Street", + "age": 34, + "type": "designer", + "city": "London", + "lastname": "B" + }, + "extra": { + "idFilter": { + "equal": { + "personid": 5 + } + } + }, + "meta": { + "table": { + "type": "table", + "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__persons", + "primary": [ + "personid" + ], + "name": "a", + "schema": { + "year": { + "type": "number", + "externalType": "integer", + "autocolumn": false, + "name": "year", + "constraints": { + "presence": false + } + }, + "firstname": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "firstname", + "constraints": { + "presence": false + } + }, + "personid": { + "type": "number", + "externalType": "integer", + "autocolumn": true, + "name": "personid", + "constraints": { + "presence": false + } + }, + "address": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "address", + "constraints": { + "presence": false + } + }, + "age": { + "type": "number", + "externalType": "integer", + "autocolumn": false, + "name": "age", + "constraints": { + "presence": false + } + }, + "type": { + "type": "options", + "externalType": "USER-DEFINED", + "autocolumn": false, + "name": "type", + "constraints": { + "presence": false, + "inclusion": [ + "support", + "designer", + "programmer", + "qa" + ] + } + }, + "city": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "city", + "constraints": { + "presence": false + } + }, + "lastname": { + "type": "string", + "externalType": "character varying", + "autocolumn": false, + "name": "lastname", + "constraints": { + "presence": false + } + }, + "QA": { + "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + "name": "QA", + "relationshipType": "many-to-one", + "fieldName": "qaid", + "type": "link", + "main": true, + "_id": "ccb68481c80c34217a4540a2c6c27fe46", + "foreignKey": "personid" + }, + "executor": { + "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", + "name": "executor", + "relationshipType": "many-to-one", + "fieldName": "executorid", + "type": "link", + "main": true, + "_id": "c89530b9770d94bec851e062b5cff3001", + "foreignKey": "personid", + "tableName": "persons" + } + }, + "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", + "sourceType": "external", + "primaryDisplay": "firstname", + "views": {} + } + }, + "tableAliases": { + "persons": "a", + "tasks": "b" + } +} \ No newline at end of file From 9a8c31a2a42bc616d096b2d76e0e015c3ac18983 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 5 Feb 2024 18:57:16 +0000 Subject: [PATCH 016/213] Handling deletion of rows that violate constraints, this has been an issue in Budibase for some time and causes some confusion, attempting to resolve this when deleting rows. --- .../api/controllers/row/ExternalRequest.ts | 91 ++++++++++++++++--- 1 file changed, 76 insertions(+), 15 deletions(-) diff --git a/packages/server/src/api/controllers/row/ExternalRequest.ts b/packages/server/src/api/controllers/row/ExternalRequest.ts index 2f3c1ad557..4f755845dc 100644 --- a/packages/server/src/api/controllers/row/ExternalRequest.ts +++ b/packages/server/src/api/controllers/row/ExternalRequest.ts @@ -7,6 +7,7 @@ import { FilterType, IncludeRelationship, ManyToManyRelationshipFieldMetadata, + ManyToOneRelationshipFieldMetadata, OneToManyRelationshipFieldMetadata, Operation, PaginationJson, @@ -102,6 +103,26 @@ function buildFilters( } } +function removeRelationships( + rowId: string, + table: Table, + isManyToMany: boolean, + colName?: string +) { + const tableId = table._id! + const filters = buildFilters(rowId, {}, table) + // safety check, if there are no filters on deletion bad things happen + if (Object.keys(filters).length !== 0) { + const op = isManyToMany ? Operation.DELETE : Operation.UPDATE + const body = colName && !isManyToMany ? { [colName]: null } : undefined + return getDatasourceAndQuery({ + endpoint: getEndpoint(tableId, op), + body, + filters, + }) + } +} + /** * This function checks the incoming parameters to make sure all the inputs are * valid based on on the table schema. The main thing this is looking for is when a @@ -305,6 +326,18 @@ export class ExternalRequest { } } + async getRow(table: Table, rowId: string): Promise { + const response = await getDatasourceAndQuery({ + endpoint: getEndpoint(table._id!, Operation.READ), + filters: buildFilters(rowId, {}, table), + }) + if (response.length > 0) { + return response[0] + } else { + throw new Error(`Cannot fetch row by ID "${rowId}"`) + } + } + inputProcessing(row: Row | undefined, table: Table) { if (!row) { return { row, manyRelationships: [] } @@ -572,7 +605,9 @@ export class ExternalRequest { * information. */ async lookupRelations(tableId: string, row: Row) { - const related: { [key: string]: any } = {} + const related: { + [key: string]: { rows: Row[]; isMany: boolean; tableId: string } + } = {} const { tableName } = breakExternalTableId(tableId) if (!tableName) { return related @@ -591,7 +626,7 @@ export class ExternalRequest { continue } const isMany = field.relationshipType === RelationshipType.MANY_TO_MANY - const tableId = isMany ? field.through : field.tableId + const tableId = isMany ? field.through! : field.tableId! const { tableName: relatedTableName } = breakExternalTableId(tableId) // @ts-ignore const linkPrimaryKey = this.tables[relatedTableName].primary[0] @@ -610,7 +645,7 @@ export class ExternalRequest { }, }) // this is the response from knex if no rows found - const rows = !response[0].read ? response : [] + const rows: Row[] = !response[0].read ? response : [] const storeTo = isMany ? field.throughFrom || linkPrimaryKey : fieldName related[storeTo] = { rows, isMany, tableId } } @@ -698,24 +733,46 @@ export class ExternalRequest { continue } for (let row of rows) { - const filters = buildFilters(generateIdForRow(row, table), {}, table) - // safety check, if there are no filters on deletion bad things happen - if (Object.keys(filters).length !== 0) { - const op = isMany ? Operation.DELETE : Operation.UPDATE - const body = isMany ? undefined : { [colName]: null } - promises.push( - getDatasourceAndQuery({ - endpoint: getEndpoint(tableId, op), - body, - filters, - }) - ) + const promise = removeRelationships( + generateIdForRow(row, table), + table, + isMany, + colName + ) + if (promise) { + promises.push(promise) } } } await Promise.all(promises) } + async removeRelationshipsToRow(table: Table, rowId: string) { + const row = await this.getRow(table, rowId) + const related = await this.lookupRelations(table._id!, row) + for (let column of Object.values(table.schema)) { + if ( + column.type !== FieldType.LINK || + column.relationshipType === RelationshipType.ONE_TO_MANY + ) { + continue + } + const relationshipColumn = column as ManyToOneRelationshipFieldMetadata + const { rows, isMany, tableId } = related[relationshipColumn.fieldName] + const table = this.getTable(tableId)! + await Promise.all( + rows.map(row => + removeRelationships( + generateIdForRow(row, table), + table, + isMany, + relationshipColumn.fieldName + ) + ) + ) + } + } + /** * This function is a bit crazy, but the exact purpose of it is to protect against the scenario in which * you have column overlap in relationships, e.g. we join a few different tables and they all have the @@ -828,6 +885,10 @@ export class ExternalRequest { } const aliasing = new AliasTables(Object.keys(this.tables)) + // remove any relationships that could block deletion + if (operation === Operation.DELETE && id) { + await this.removeRelationshipsToRow(table, generateRowIdField(id)) + } const response = await aliasing.queryWithAliasing(json) // handle many-to-many relationships now if we know the ID (could be auto increment) if (operation !== Operation.READ) { From d7ae4c04b9e84e48ab3bc3553ed5e39aa6e3e414 Mon Sep 17 00:00:00 2001 From: Mitch-Budibase Date: Tue, 6 Feb 2024 17:15:11 +0000 Subject: [PATCH 017/213] Removing commented line --- qa-core/src/account-api/tests/licensing/license.manage.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/qa-core/src/account-api/tests/licensing/license.manage.spec.ts b/qa-core/src/account-api/tests/licensing/license.manage.spec.ts index 2d5b9332c6..baed5734cf 100644 --- a/qa-core/src/account-api/tests/licensing/license.manage.spec.ts +++ b/qa-core/src/account-api/tests/licensing/license.manage.spec.ts @@ -105,7 +105,6 @@ describe("license management", () => { expect(portalSessionBody.url).toContain("billing.stripe.com") // Update subscription from premium to business license - //await config.api.licenses.updatePlan(businessPriceId.priceId) await config.api.licenses.updatePlan(businessPriceId) // License updated to Business From 3726e10f3a6bee0f40e9f3f86da6bd6d7c309af5 Mon Sep 17 00:00:00 2001 From: Mitch-Budibase Date: Tue, 6 Feb 2024 17:28:00 +0000 Subject: [PATCH 018/213] lint --- .../src/account-api/tests/licensing/license.manage.spec.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qa-core/src/account-api/tests/licensing/license.manage.spec.ts b/qa-core/src/account-api/tests/licensing/license.manage.spec.ts index baed5734cf..85ee530bb7 100644 --- a/qa-core/src/account-api/tests/licensing/license.manage.spec.ts +++ b/qa-core/src/account-api/tests/licensing/license.manage.spec.ts @@ -48,9 +48,10 @@ describe("license management", () => { } // Create checkout session for price - const checkoutSessionRes = await config.api.stripe.createCheckoutSession( - { id: premiumPrice.priceId, type: premiumPrice.type } - ) + const checkoutSessionRes = await config.api.stripe.createCheckoutSession({ + id: premiumPrice.priceId, + type: premiumPrice.type, + }) const checkoutSessionUrl = checkoutSessionRes[1].url expect(checkoutSessionUrl).toContain("checkout.stripe.com") From 6f6100e7a24d7936a56271d5202d87ed2b76079d Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 12 Feb 2024 18:07:17 +0100 Subject: [PATCH 019/213] Use isolated-vm --- packages/server/src/jsRunner/index.ts | 83 +++++++------------ packages/server/src/threads/query.ts | 14 +++- packages/server/src/utilities/scriptRunner.ts | 46 ++++++---- 3 files changed, 67 insertions(+), 76 deletions(-) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index e39dab1313..93383b3955 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -1,68 +1,41 @@ -import vm from "vm" import env from "../environment" -import { setJSRunner, setOnErrorLog } from "@budibase/string-templates" -import { context, logging, timers } from "@budibase/backend-core" +import { setJSRunner, JsErrorTimeout } from "@budibase/string-templates" import tracer from "dd-trace" -import { serializeError } from "serialize-error" -type TrackerFn = (f: () => T) => T +import { IsolatedVM } from "./vm" +import { context } from "@budibase/backend-core" export function init() { - setJSRunner((js: string, ctx: vm.Context) => { + setJSRunner((js: string, ctx: Record) => { return tracer.trace("runJS", {}, span => { - const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS - let track: TrackerFn = f => f() - if (perRequestLimit) { - const bbCtx = tracer.trace("runJS.getCurrentContext", {}, span => - context.getCurrentContext() - ) - if (bbCtx) { - if (!bbCtx.jsExecutionTracker) { - span?.addTags({ - createdExecutionTracker: true, - }) - bbCtx.jsExecutionTracker = tracer.trace( - "runJS.createExecutionTimeTracker", - {}, - span => timers.ExecutionTimeTracker.withLimit(perRequestLimit) - ) - } - span?.addTags({ - js: { - limitMS: bbCtx.jsExecutionTracker.limitMs, - elapsedMS: bbCtx.jsExecutionTracker.elapsedMS, - }, - }) - // We call checkLimit() here to prevent paying the cost of creating - // a new VM context below when we don't need to. - tracer.trace("runJS.checkLimitAndBind", {}, span => { - bbCtx.jsExecutionTracker!.checkLimit() - track = bbCtx.jsExecutionTracker!.track.bind( - bbCtx.jsExecutionTracker - ) + try { + const bbCtx = context.getCurrentContext()! + + let { vm } = bbCtx + if (!vm) { + // Can't copy the native helpers into the isolate. We just ignore them as they are handled properly from the helpersSource + const { helpers, ...ctxToPass } = ctx + + vm = new IsolatedVM({ + memoryLimit: env.JS_RUNNER_MEMORY_LIMIT, + invocationTimeout: env.JS_PER_INVOCATION_TIMEOUT_MS, + isolateAccumulatedTimeout: env.JS_PER_REQUEST_TIMEOUT_MS, }) + .withContext(ctxToPass) + .withHelpers() + + bbCtx.vm = vm } - } - ctx = { - ...ctx, - alert: undefined, - setInterval: undefined, - setTimeout: undefined, - } + const result = vm.execute(js) - vm.createContext(ctx) - return track(() => - vm.runInNewContext(js, ctx, { - timeout: env.JS_PER_INVOCATION_TIMEOUT_MS, - }) - ) + return result + } catch (error: any) { + if (error.message === "Script execution timed out.") { + throw new JsErrorTimeout() + } + throw error + } }) }) - - if (env.LOG_JS_ERRORS) { - setOnErrorLog((error: Error) => { - logging.logWarn(JSON.stringify(serializeError(error))) - }) - } } diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index 6b11ce4759..b38dd7de6b 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -127,10 +127,16 @@ class QueryRunner { // transform as required if (transformer) { - const runner = new ScriptRunner(transformer, { - data: rows, - params: enrichedParameters, - }) + const runner = new ScriptRunner( + transformer, + { + data: rows, + params: enrichedParameters, + }, + { + parseBson: datasource.source === SourceName.MONGODB, + } + ) rows = runner.execute() } diff --git a/packages/server/src/utilities/scriptRunner.ts b/packages/server/src/utilities/scriptRunner.ts index fee0215d2e..72042a5791 100644 --- a/packages/server/src/utilities/scriptRunner.ts +++ b/packages/server/src/utilities/scriptRunner.ts @@ -1,28 +1,40 @@ -import fetch from "node-fetch" -import { VM, VMScript } from "vm2" +import tracer, { Span } from "dd-trace" +import env from "../environment" +import { IsolatedVM } from "../jsRunner/vm" const JS_TIMEOUT_MS = 1000 class ScriptRunner { - vm: VM - results: { out: string } - script: VMScript + private code: string + private vm: IsolatedVM - constructor(script: string, context: any) { - const code = `let fn = () => {\n${script}\n}; results.out = fn();` - this.vm = new VM({ - timeout: JS_TIMEOUT_MS, - }) - this.results = { out: "" } - this.vm.setGlobals(context) - this.vm.setGlobal("fetch", fetch) - this.vm.setGlobal("results", this.results) - this.script = new VMScript(code) + private tracerSpan: Span + + constructor(script: string, context: any, { parseBson = false } = {}) { + this.tracerSpan = tracer.startSpan("scriptRunner", { tags: { parseBson } }) + + this.code = `(() => {${script}})();` + this.vm = new IsolatedVM({ + memoryLimit: env.JS_RUNNER_MEMORY_LIMIT, + invocationTimeout: JS_TIMEOUT_MS, + }).withContext(context) + + if (parseBson && context.data) { + this.vm = this.vm.withParsingBson(context.data) + } } execute() { - this.vm.run(this.script) - return this.results.out + const result = tracer.trace( + "scriptRunner.execute", + { childOf: this.tracerSpan }, + () => { + const result = this.vm.execute(this.code) + return result + } + ) + this.tracerSpan.finish() + return result } } From f0a149984d4623bb0e9883d9f425e372cad67b6a Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 09:48:31 +0100 Subject: [PATCH 020/213] Update tests --- .../src/jsRunner/tests/jsRunner.spec.ts | 58 +++++++------------ 1 file changed, 20 insertions(+), 38 deletions(-) diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts index 04f1bf20f1..285ade7097 100644 --- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts +++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts @@ -1,21 +1,4 @@ -// import { validate as isValidUUID } from "uuid" - -jest.mock("@budibase/handlebars-helpers/lib/math", () => { - const actual = jest.requireActual("@budibase/handlebars-helpers/lib/math") - - return { - ...actual, - random: () => 10, - } -}) -jest.mock("@budibase/handlebars-helpers/lib/uuid", () => { - const actual = jest.requireActual("@budibase/handlebars-helpers/lib/uuid") - - return { - ...actual, - uuid: () => "f34ebc66-93bd-4f7c-b79b-92b5569138bc", - } -}) +import { validate as isValidUUID } from "uuid" import { processStringSync, encodeJSBinding } from "@budibase/string-templates" @@ -47,8 +30,7 @@ describe("jsRunner", () => { expect(output).toBe(3) }) - // TODO This should be reenabled when running on isolated-vm - it.skip("should prevent sandbox escape", async () => { + it("should prevent sandbox escape", async () => { const output = await processJS( `return this.constructor.constructor("return process")()` ) @@ -58,26 +40,26 @@ describe("jsRunner", () => { describe("helpers", () => { runJsHelpersTests({ funcWrap: (func: any) => config.doInContext(config.getAppId(), func), - // testsToSkip: ["random", "uuid"], + testsToSkip: ["random", "uuid"], }) - // describe("uuid", () => { - // it("uuid helper returns a valid uuid", async () => { - // const result = await processJS("return helpers.uuid()") - // expect(result).toBeDefined() - // expect(isValidUUID(result)).toBe(true) - // }) - // }) + describe("uuid", () => { + it("uuid helper returns a valid uuid", async () => { + const result = await processJS("return helpers.uuid()") + expect(result).toBeDefined() + expect(isValidUUID(result)).toBe(true) + }) + }) - // describe("random", () => { - // it("random helper returns a valid number", async () => { - // const min = 1 - // const max = 8 - // const result = await processJS(`return helpers.random(${min}, ${max})`) - // expect(result).toBeDefined() - // expect(result).toBeGreaterThanOrEqual(min) - // expect(result).toBeLessThanOrEqual(max) - // }) - // }) + describe("random", () => { + it("random helper returns a valid number", async () => { + const min = 1 + const max = 8 + const result = await processJS(`return helpers.random(${min}, ${max})`) + expect(result).toBeDefined() + expect(result).toBeGreaterThanOrEqual(min) + expect(result).toBeLessThanOrEqual(max) + }) + }) }) }) From ea9811b9864bacd7b520639723b2eaac68e2c0bb Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 13 Feb 2024 11:51:45 +0000 Subject: [PATCH 021/213] Update CouchDB image to bookworm and couchdb 3.3.3. --- hosting/couchdb/Dockerfile | 97 +++++++++++++++- hosting/couchdb/clouseau/clouseau.ini | 2 +- hosting/couchdb/couch/10-docker-default.ini | 8 ++ hosting/couchdb/couch/vm.args | 2 +- hosting/couchdb/docker-entrypoint.sh | 121 ++++++++++++++++++++ hosting/couchdb/runner.sh | 4 + hosting/single/runner.sh | 6 +- packages/server/src/jsRunner/index.ts | 4 + 8 files changed, 237 insertions(+), 7 deletions(-) create mode 100644 hosting/couchdb/couch/10-docker-default.ini create mode 100755 hosting/couchdb/docker-entrypoint.sh diff --git a/hosting/couchdb/Dockerfile b/hosting/couchdb/Dockerfile index f83df7038b..6f940d6c48 100644 --- a/hosting/couchdb/Dockerfile +++ b/hosting/couchdb/Dockerfile @@ -1,4 +1,95 @@ -FROM couchdb:3.2.1 +# Modified from https://github.com/apache/couchdb-docker/blob/main/3.2.1/Dockerfile +FROM debian:bookworm-slim + +# Add CouchDB user account to make sure the IDs are assigned consistently +RUN groupadd -g 5984 -r couchdb && useradd -u 5984 -d /opt/couchdb -g couchdb couchdb + +# be sure GPG and apt-transport-https are available and functional +RUN set -ex; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + apt-transport-https \ + ca-certificates \ + dirmngr \ + gnupg \ + ; \ + rm -rf /var/lib/apt/lists/* + +# grab gosu for easy step-down from root and tini for signal handling and zombie reaping +# see https://github.com/apache/couchdb-docker/pull/28#discussion_r141112407 +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends gosu tini; \ + rm -rf /var/lib/apt/lists/*; \ + gosu nobody true; \ + tini --version + +# http://docs.couchdb.org/en/latest/install/unix.html#installing-the-apache-couchdb-packages +ENV GPG_COUCH_KEY \ +# gpg: rsa8192 205-01-19 The Apache Software Foundation (Package repository signing key) + 390EF70BB1EA12B2773962950EE62FB37A00258D +RUN set -eux; \ + apt-get update; \ + apt-get install -y curl; \ + export GNUPGHOME="$(mktemp -d)"; \ + curl -fL -o keys.asc https://couchdb.apache.org/repo/keys.asc; \ + gpg --batch --import keys.asc; \ + gpg --batch --export "${GPG_COUCH_KEY}" > /usr/share/keyrings/couchdb-archive-keyring.gpg; \ + command -v gpgconf && gpgconf --kill all || :; \ + rm -rf "$GNUPGHOME"; \ + apt-key list; \ + apt purge -y --autoremove curl; \ + rm -rf /var/lib/apt/lists/* + +ENV COUCHDB_VERSION 3.3.3 + +RUN . /etc/os-release; \ + echo "deb [signed-by=/usr/share/keyrings/couchdb-archive-keyring.gpg] https://apache.jfrog.io/artifactory/couchdb-deb/ ${VERSION_CODENAME} main" | \ + tee /etc/apt/sources.list.d/couchdb.list >/dev/null + +# https://github.com/apache/couchdb-pkg/blob/master/debian/README.Debian +RUN set -eux; \ + apt-get update; \ + \ + echo "couchdb couchdb/mode select none" | debconf-set-selections; \ +# we DO want recommends this time + DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-downgrades --allow-remove-essential --allow-change-held-packages \ + couchdb="$COUCHDB_VERSION"~bookworm \ + ; \ +# Undo symlinks to /var/log and /var/lib + rmdir /var/lib/couchdb /var/log/couchdb; \ + rm /opt/couchdb/data /opt/couchdb/var/log; \ + mkdir -p /opt/couchdb/data /opt/couchdb/var/log; \ + chown couchdb:couchdb /opt/couchdb/data /opt/couchdb/var/log; \ + chmod 777 /opt/couchdb/data /opt/couchdb/var/log; \ +# Remove file that sets logging to a file + rm /opt/couchdb/etc/default.d/10-filelog.ini; \ +# Check we own everything in /opt/couchdb. Matches the command in dockerfile_entrypoint.sh + find /opt/couchdb \! \( -user couchdb -group couchdb \) -exec chown -f couchdb:couchdb '{}' +; \ +# Setup directories and permissions for config. Technically these could be 555 and 444 respectively +# but we keep them as 755 and 644 for consistency with CouchDB defaults and the dockerfile_entrypoint.sh. + find /opt/couchdb/etc -type d ! -perm 0755 -exec chmod -f 0755 '{}' +; \ + find /opt/couchdb/etc -type f ! -perm 0644 -exec chmod -f 0644 '{}' +; \ +# only local.d needs to be writable for the docker_entrypoint.sh + chmod -f 0777 /opt/couchdb/etc/local.d; \ +# apt clean-up + rm -rf /var/lib/apt/lists/*; + +# Add configuration +COPY --chown=couchdb:couchdb couch/10-docker-default.ini /opt/couchdb/etc/default.d/ +# COPY --chown=couchdb:couchdb vm.args /opt/couchdb/etc/ + +COPY docker-entrypoint.sh /usr/local/bin +RUN ln -s usr/local/bin/docker-entrypoint.sh /docker-entrypoint.sh # backwards compat +ENTRYPOINT ["tini", "--", "/docker-entrypoint.sh"] + +VOLUME /opt/couchdb/data + +# 5984: Main CouchDB endpoint +# 4369: Erlang portmap daemon (epmd) +# 9100: CouchDB cluster communication port +EXPOSE 5984 4369 9100 +# CMD ["/opt/couchdb/bin/couchdb"] ENV COUCHDB_USER admin ENV COUCHDB_PASSWORD admin @@ -6,9 +97,9 @@ EXPOSE 5984 RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common wget unzip curl && \ wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | apt-key add - && \ - apt-add-repository 'deb http://security.debian.org/debian-security bullseye-security/updates main' && \ + apt-add-repository 'deb http://security.debian.org/debian-security bookworm-security/updates main' && \ apt-add-repository 'deb http://archive.debian.org/debian stretch-backports main' && \ - apt-add-repository 'deb https://packages.adoptium.net/artifactory/deb bullseye main' && \ + apt-add-repository 'deb https://packages.adoptium.net/artifactory/deb bookworm main' && \ apt-get update && apt-get install -y --no-install-recommends temurin-8-jdk && \ rm -rf /var/lib/apt/lists/ diff --git a/hosting/couchdb/clouseau/clouseau.ini b/hosting/couchdb/clouseau/clouseau.ini index 578a5acafa..014fb854f3 100644 --- a/hosting/couchdb/clouseau/clouseau.ini +++ b/hosting/couchdb/clouseau/clouseau.ini @@ -4,7 +4,7 @@ name=clouseau@127.0.0.1 ; set this to the same distributed Erlang cookie used by the CouchDB nodes -cookie=monster +cookie=COUCHDB_ERLANG_COOKIE ; the path where you would like to store the search index files dir=DATA_DIR/search diff --git a/hosting/couchdb/couch/10-docker-default.ini b/hosting/couchdb/couch/10-docker-default.ini new file mode 100644 index 0000000000..1aa633cbfc --- /dev/null +++ b/hosting/couchdb/couch/10-docker-default.ini @@ -0,0 +1,8 @@ +; CouchDB Configuration Settings + +; Custom settings should be made in this file. They will override settings +; in default.ini, but unlike changes made to default.ini, this file won't be +; overwritten on server upgrade. + +[chttpd] +bind_address = any diff --git a/hosting/couchdb/couch/vm.args b/hosting/couchdb/couch/vm.args index e9e4416863..11845dd6d4 100644 --- a/hosting/couchdb/couch/vm.args +++ b/hosting/couchdb/couch/vm.args @@ -12,7 +12,7 @@ # erlang cookie for clouseau security -name couchdb@127.0.0.1 --setcookie monster +-setcookie COUCHDB_ERLANG_COOKIE # Ensure that the Erlang VM listens on a known port -kernel inet_dist_listen_min 9100 diff --git a/hosting/couchdb/docker-entrypoint.sh b/hosting/couchdb/docker-entrypoint.sh new file mode 100755 index 0000000000..8d6456d577 --- /dev/null +++ b/hosting/couchdb/docker-entrypoint.sh @@ -0,0 +1,121 @@ +#!/bin/bash +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +set -e + +# first arg is `-something` or `+something` +if [ "${1#-}" != "$1" ] || [ "${1#+}" != "$1" ]; then + set -- /opt/couchdb/bin/couchdb "$@" +fi + +# first arg is the bare word `couchdb` +if [ "$1" = 'couchdb' ]; then + shift + set -- /opt/couchdb/bin/couchdb "$@" +fi + +if [ "$1" = '/opt/couchdb/bin/couchdb' ]; then + # this is where runtime configuration changes will be written. + # we need to explicitly touch it here in case /opt/couchdb/etc has + # been mounted as an external volume, in which case it won't exist. + # If running as the couchdb user (i.e. container starts as root), + # write permissions will be granted below. + touch /opt/couchdb/etc/local.d/docker.ini + + # if user is root, assume running under the couchdb user (default) + # and ensure it is able to access files and directories that may be mounted externally + if [ "$(id -u)" = '0' ]; then + # Check that we own everything in /opt/couchdb and fix if necessary. We also + # add the `-f` flag in all the following invocations because there may be + # cases where some of these ownership and permissions issues are non-fatal + # (e.g. a config file owned by root with o+r is actually fine), and we don't + # to be too aggressive about crashing here ... + find /opt/couchdb \! \( -user couchdb -group couchdb \) -exec chown -f couchdb:couchdb '{}' + + + # Ensure that data files have the correct permissions. We were previously + # preventing any access to these files outside of couchdb:couchdb, but it + # turns out that CouchDB itself does not set such restrictive permissions + # when it creates the files. The approach taken here ensures that the + # contents of the datadir have the same permissions as they had when they + # were initially created. This should minimize any startup delay. + find /opt/couchdb/data -type d ! -perm 0755 -exec chmod -f 0755 '{}' + + find /opt/couchdb/data -type f ! -perm 0644 -exec chmod -f 0644 '{}' + + + # Do the same thing for configuration files and directories. Technically + # CouchDB only needs read access to the configuration files as all online + # changes will be applied to the "docker.ini" file below, but we set 644 + # for the sake of consistency. + find /opt/couchdb/etc -type d ! -perm 0755 -exec chmod -f 0755 '{}' + + find /opt/couchdb/etc -type f ! -perm 0644 -exec chmod -f 0644 '{}' + + fi + + if [ ! -z "$NODENAME" ] && ! grep "couchdb@" /opt/couchdb/etc/vm.args; then + echo "-name couchdb@$NODENAME" >> /opt/couchdb/etc/vm.args + fi + + if [ "$COUCHDB_USER" ] && [ "$COUCHDB_PASSWORD" ]; then + # Create admin only if not already present + if ! grep -Pzoqr "\[admins\]\n$COUCHDB_USER =" /opt/couchdb/etc/local.d/*.ini /opt/couchdb/etc/local.ini; then + printf "\n[admins]\n%s = %s\n" "$COUCHDB_USER" "$COUCHDB_PASSWORD" >> /opt/couchdb/etc/local.d/docker.ini + fi + fi + + if [ "$COUCHDB_SECRET" ]; then + # Set secret only if not already present + if ! grep -Pzoqr "\[chttpd_auth\]\nsecret =" /opt/couchdb/etc/local.d/*.ini /opt/couchdb/etc/local.ini; then + printf "\n[chttpd_auth]\nsecret = %s\n" "$COUCHDB_SECRET" >> /opt/couchdb/etc/local.d/docker.ini + fi + fi + + if [ "$COUCHDB_ERLANG_COOKIE" ]; then + cookieFile='/opt/couchdb/.erlang.cookie' + if [ -e "$cookieFile" ]; then + if [ "$(cat "$cookieFile" 2>/dev/null)" != "$COUCHDB_ERLANG_COOKIE" ]; then + echo >&2 + echo >&2 "warning: $cookieFile contents do not match COUCHDB_ERLANG_COOKIE" + echo >&2 + fi + else + echo "$COUCHDB_ERLANG_COOKIE" > "$cookieFile" + fi + chown couchdb:couchdb "$cookieFile" + chmod 600 "$cookieFile" + fi + + if [ "$(id -u)" = '0' ]; then + chown -f couchdb:couchdb /opt/couchdb/etc/local.d/docker.ini || true + fi + + # if we don't find an [admins] section followed by a non-comment, display a warning + if ! grep -Pzoqr '\[admins\]\n[^;]\w+' /opt/couchdb/etc/default.d/*.ini /opt/couchdb/etc/local.d/*.ini /opt/couchdb/etc/local.ini; then + # The - option suppresses leading tabs but *not* spaces. :) + cat >&2 <<-'EOWARN' +************************************************************* +ERROR: CouchDB 3.0+ will no longer run in "Admin Party" + mode. You *MUST* specify an admin user and + password, either via your own .ini file mapped + into the container at /opt/couchdb/etc/local.ini + or inside /opt/couchdb/etc/local.d, or with + "-e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password" + to set it via "docker run". +************************************************************* +EOWARN + exit 1 + fi + + if [ "$(id -u)" = '0' ]; then + exec gosu couchdb "$@" + fi +fi + +exec "$@" diff --git a/hosting/couchdb/runner.sh b/hosting/couchdb/runner.sh index 9f6a853ca7..aaadee6b43 100644 --- a/hosting/couchdb/runner.sh +++ b/hosting/couchdb/runner.sh @@ -1,6 +1,7 @@ #!/bin/bash DATA_DIR=${DATA_DIR:-/data} +COUCHDB_ERLANG_COOKIE=${COUCHDB_ERLANG_COOKIE:-B9CFC32C-3458-4A86-8448-B3C753991CA7} mkdir -p ${DATA_DIR} mkdir -p ${DATA_DIR}/couch/{dbs,views} @@ -60,6 +61,9 @@ else sed -i "s#DATA_DIR#/data#g" /opt/couchdb/etc/local.ini fi +sed -i "s#COUCHDB_ERLANG_COOKIE#${COUCHDB_ERLANG_COOKIE}#g" /opt/couchdb/etc/vm.args +sed -i "s#COUCHDB_ERLANG_COOKIE#${COUCHDB_ERLANG_COOKIE}#g" /opt/clouseau/clouseau.ini + # Start Clouseau. Budibase won't function correctly without Clouseau running, it # powers the search API endpoints which are used to do all sorts, including # populating app grids. diff --git a/hosting/single/runner.sh b/hosting/single/runner.sh index 886da4c916..3126eedfb1 100644 --- a/hosting/single/runner.sh +++ b/hosting/single/runner.sh @@ -97,10 +97,12 @@ fi sleep 10 pushd app -pm2 start -l /dev/stdout --name app "yarn run:docker" +pm2 start --name app "yarn run:docker" popd pushd worker -pm2 start -l /dev/stdout --name worker "yarn run:docker" +pm2 start --name worker "yarn run:docker" popd echo "end of runner.sh, sleeping ..." + +tail -f $HOME/.pm2/logs/*.log sleep infinity diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index e39dab1313..84fe6e65c8 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -4,11 +4,15 @@ import { setJSRunner, setOnErrorLog } from "@budibase/string-templates" import { context, logging, timers } from "@budibase/backend-core" import tracer from "dd-trace" import { serializeError } from "serialize-error" +import { IsolatedVM } from "./vm" type TrackerFn = (f: () => T) => T export function init() { setJSRunner((js: string, ctx: vm.Context) => { + const ivm = new IsolatedVM({ memoryLimit: 10, invocationTimeout: 1000 }) + ivm.withContext(ctx) + return tracer.trace("runJS", {}, span => { const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS let track: TrackerFn = f => f() From 140ff2d985876084a510a16031e19fb68178f500 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 13 Feb 2024 12:08:25 +0000 Subject: [PATCH 022/213] Use node:20-slim as the base for consistency with app images. --- hosting/couchdb/Dockerfile | 2 +- hosting/single/Dockerfile | 10 +++------- scripts/install-node.sh | 8 -------- 3 files changed, 4 insertions(+), 16 deletions(-) delete mode 100644 scripts/install-node.sh diff --git a/hosting/couchdb/Dockerfile b/hosting/couchdb/Dockerfile index 6f940d6c48..b4dbdd36dc 100644 --- a/hosting/couchdb/Dockerfile +++ b/hosting/couchdb/Dockerfile @@ -1,5 +1,5 @@ # Modified from https://github.com/apache/couchdb-docker/blob/main/3.2.1/Dockerfile -FROM debian:bookworm-slim +FROM node:20-slim # Add CouchDB user account to make sure the IDs are assigned consistently RUN groupadd -g 5984 -r couchdb && useradd -u 5984 -d /opt/couchdb -g couchdb couchdb diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile index f9044cd124..a928766541 100644 --- a/hosting/single/Dockerfile +++ b/hosting/single/Dockerfile @@ -3,7 +3,6 @@ FROM node:20-slim as build # install node-gyp dependencies RUN apt-get update && apt-get install -y --no-install-recommends g++ make python3 jq - # copy and install dependencies WORKDIR /app COPY package.json . @@ -39,10 +38,9 @@ COPY packages/worker/pm2.config.js packages/worker/pm2.config.js COPY packages/string-templates packages/string-templates -FROM budibase/couchdb as runner +FROM budicouch as runner ARG TARGETARCH ENV TARGETARCH $TARGETARCH -ENV NODE_MAJOR 20 #TARGETBUILD can be set to single (for single docker image) or aas (for azure app service) # e.g. docker build --build-arg TARGETBUILD=aas .... ARG TARGETBUILD=single @@ -60,10 +58,8 @@ RUN apt install -y software-properties-common apt-transport-https ca-certificate && apt install postgresql-client-15 -y \ && apt remove software-properties-common apt-transport-https gpg -y -# install other dependencies, nodejs, oracle requirements, jdk8, redis, nginx -WORKDIR /nodejs -COPY scripts/install-node.sh ./install.sh -RUN chmod +x install.sh && ./install.sh +# We use pm2 in order to run multiple node processes in a single container +RUN npm install --global pm2 # setup nginx COPY hosting/single/nginx/nginx.conf /etc/nginx diff --git a/scripts/install-node.sh b/scripts/install-node.sh deleted file mode 100644 index 562bdf2cd3..0000000000 --- a/scripts/install-node.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -apt-get install -y gnupg -curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | tee /usr/share/keyrings/nodesource.gpg > /dev/null -echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list -apt-get update -echo "INSTALLING NODE $NODE_MAJOR" -apt-get install -y --no-install-recommends nodejs -npm install --global yarn pm2 \ No newline at end of file From f6137e097457c9fcafae88085f3cb8ecbeebb568 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 13 Feb 2024 12:09:00 +0000 Subject: [PATCH 023/213] Put the couchdb reference back in the single image build. --- hosting/single/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile index a928766541..f89967cb0b 100644 --- a/hosting/single/Dockerfile +++ b/hosting/single/Dockerfile @@ -38,7 +38,7 @@ COPY packages/worker/pm2.config.js packages/worker/pm2.config.js COPY packages/string-templates packages/string-templates -FROM budicouch as runner +FROM budibase/couchdb as runner ARG TARGETARCH ENV TARGETARCH $TARGETARCH #TARGETBUILD can be set to single (for single docker image) or aas (for azure app service) From 4bcf1332593f298c0bb6781d4f0902bdc4e449df Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 13 Feb 2024 12:18:16 +0000 Subject: [PATCH 024/213] Remove unneeded jsRunner/index.ts code. --- packages/server/src/jsRunner/index.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index 84fe6e65c8..e39dab1313 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -4,15 +4,11 @@ import { setJSRunner, setOnErrorLog } from "@budibase/string-templates" import { context, logging, timers } from "@budibase/backend-core" import tracer from "dd-trace" import { serializeError } from "serialize-error" -import { IsolatedVM } from "./vm" type TrackerFn = (f: () => T) => T export function init() { setJSRunner((js: string, ctx: vm.Context) => { - const ivm = new IsolatedVM({ memoryLimit: 10, invocationTimeout: 1000 }) - ivm.withContext(ctx) - return tracer.trace("runJS", {}, span => { const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS let track: TrackerFn = f => f() From 634b3b43dd3ba22b7e3a320436311bf5a9402d96 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 13 Feb 2024 15:35:44 +0000 Subject: [PATCH 025/213] Better delineate what is our CouchDB image and what is from the official one. --- hosting/couchdb/Dockerfile | 16 +++++++++++----- hosting/couchdb/docker-entrypoint.sh | 5 +++-- hosting/single/Dockerfile | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/hosting/couchdb/Dockerfile b/hosting/couchdb/Dockerfile index b4dbdd36dc..6dbf2be08b 100644 --- a/hosting/couchdb/Dockerfile +++ b/hosting/couchdb/Dockerfile @@ -1,5 +1,10 @@ # Modified from https://github.com/apache/couchdb-docker/blob/main/3.2.1/Dockerfile -FROM node:20-slim +# +# Everything in this `base` image is adapted from the official `couchdb` image's +# Dockerfile. Only modifications related to upgrading from Debian bullseye to +# bookworm have been included. The `runner` image contains Budibase's +# customisations to the image, e.g. adding Clouseau. +FROM node:20-slim AS base # Add CouchDB user account to make sure the IDs are assigned consistently RUN groupadd -g 5984 -r couchdb && useradd -u 5984 -d /opt/couchdb -g couchdb couchdb @@ -15,13 +20,12 @@ RUN set -ex; \ ; \ rm -rf /var/lib/apt/lists/* -# grab gosu for easy step-down from root and tini for signal handling and zombie reaping +# grab tini for signal handling and zombie reaping # see https://github.com/apache/couchdb-docker/pull/28#discussion_r141112407 RUN set -eux; \ apt-get update; \ - apt-get install -y --no-install-recommends gosu tini; \ + apt-get install -y --no-install-recommends tini; \ rm -rf /var/lib/apt/lists/*; \ - gosu nobody true; \ tini --version # http://docs.couchdb.org/en/latest/install/unix.html#installing-the-apache-couchdb-packages @@ -89,7 +93,9 @@ VOLUME /opt/couchdb/data # 4369: Erlang portmap daemon (epmd) # 9100: CouchDB cluster communication port EXPOSE 5984 4369 9100 -# CMD ["/opt/couchdb/bin/couchdb"] +CMD ["/opt/couchdb/bin/couchdb"] + +FROM base as runner ENV COUCHDB_USER admin ENV COUCHDB_PASSWORD admin diff --git a/hosting/couchdb/docker-entrypoint.sh b/hosting/couchdb/docker-entrypoint.sh index 8d6456d577..bd709b7b73 100755 --- a/hosting/couchdb/docker-entrypoint.sh +++ b/hosting/couchdb/docker-entrypoint.sh @@ -114,8 +114,9 @@ EOWARN fi if [ "$(id -u)" = '0' ]; then - exec gosu couchdb "$@" + export HOME=$(echo ~couchdb) + exec setpriv --reuid=couchdb --regid=couchdb --clear-groups "$@" fi fi -exec "$@" +exec "$@" \ No newline at end of file diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile index f89967cb0b..a928766541 100644 --- a/hosting/single/Dockerfile +++ b/hosting/single/Dockerfile @@ -38,7 +38,7 @@ COPY packages/worker/pm2.config.js packages/worker/pm2.config.js COPY packages/string-templates packages/string-templates -FROM budibase/couchdb as runner +FROM budicouch as runner ARG TARGETARCH ENV TARGETARCH $TARGETARCH #TARGETBUILD can be set to single (for single docker image) or aas (for azure app service) From 22240659eb2a0107e9421bba3e030f44ed318800 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 13 Feb 2024 15:36:09 +0000 Subject: [PATCH 026/213] Link to the correct Dockerfile we've modified. --- hosting/couchdb/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/couchdb/Dockerfile b/hosting/couchdb/Dockerfile index 6dbf2be08b..36abc2dd19 100644 --- a/hosting/couchdb/Dockerfile +++ b/hosting/couchdb/Dockerfile @@ -1,4 +1,4 @@ -# Modified from https://github.com/apache/couchdb-docker/blob/main/3.2.1/Dockerfile +# Modified from https://github.com/apache/couchdb-docker/blob/main/3.3.3/Dockerfile # # Everything in this `base` image is adapted from the official `couchdb` image's # Dockerfile. Only modifications related to upgrading from Debian bullseye to From 7e43fff018b904b030ef22ec64a0df90d547c3a6 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 11:45:11 +0100 Subject: [PATCH 027/213] Execute sloppy code test --- packages/server/src/jsRunner/tests/jsRunner.spec.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts index 285ade7097..85691878bd 100644 --- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts +++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts @@ -30,6 +30,11 @@ describe("jsRunner", () => { expect(output).toBe(3) }) + it("it can execute sloppy javascript", async () => { + const output = await processJS(`a=2;b=3;return a + b`) + expect(output).toBe(5) + }) + it("should prevent sandbox escape", async () => { const output = await processJS( `return this.constructor.constructor("return process")()` From 53d4fc2fa04dd6abc6fa8475eb17cdc92c52b51d Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 14:13:09 +0100 Subject: [PATCH 028/213] Replace ivm.module for script --- .../bundles/index-helpers.ivm.bundle.js | 3554 ++++++++++++++++- .../src/jsRunner/bundles/index-helpers.ts | 5 +- packages/server/src/jsRunner/vm/index.ts | 101 +- 3 files changed, 3592 insertions(+), 68 deletions(-) diff --git a/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js b/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js index 706625b757..2201586ec0 100644 --- a/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js +++ b/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js @@ -1,4 +1,3556 @@ -var De=Object.defineProperty;var un=Object.getOwnPropertyDescriptor;var sn=Object.getOwnPropertyNames;var fn=Object.prototype.hasOwnProperty;var Ue=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Z=(e,t)=>()=>(e&&(t=e(e=0)),t);var U=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),on=(e,t)=>{for(var r in t)De(e,r,{get:t[r],enumerable:!0})},an=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of sn(t))!fn.call(e,i)&&i!==r&&De(e,i,{get:()=>t[i],enumerable:!(n=un(t,i))||n.enumerable});return e};var cn=e=>an(De({},"__esModule",{value:!0}),e);var gt=U((Te,qe)=>{(function(e,t){typeof Te=="object"&&typeof qe<"u"?qe.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs=t()})(Te,function(){"use strict";var e=1e3,t=6e4,r=36e5,n="millisecond",i="second",u="minute",s="hour",f="day",w="week",g="month",l="quarter",x="year",v="date",a="Invalid Date",T=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,E=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,I={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function($){var h=["th","st","nd","rd"],c=$%100;return"["+$+(h[(c-20)%10]||h[c]||h[0])+"]"}},Y=function($,h,c){var b=String($);return!b||b.length>=h?$:""+Array(h+1-b.length).join(c)+$},F={s:Y,z:function($){var h=-$.utcOffset(),c=Math.abs(h),b=Math.floor(c/60),d=c%60;return(h<=0?"+":"-")+Y(b,2,"0")+":"+Y(d,2,"0")},m:function $(h,c){if(h.date()1)return $(j[0])}else{var _=h.name;S[_]=h,d=_}return!b&&d&&(q=d),d||!b&&q},N=function($,h){if(o($))return $.clone();var c=typeof h=="object"?h:{};return c.date=$,c.args=arguments,new B(c)},O=F;O.l=D,O.i=o,O.w=function($,h){return N($,{locale:h.$L,utc:h.$u,x:h.$x,$offset:h.$offset})};var B=function(){function $(c){this.$L=D(c.locale,null,!0),this.parse(c),this.$x=this.$x||c.x||{},this[p]=!0}var h=$.prototype;return h.parse=function(c){this.$d=function(b){var d=b.date,M=b.utc;if(d===null)return new Date(NaN);if(O.u(d))return new Date;if(d instanceof Date)return new Date(d);if(typeof d=="string"&&!/Z$/i.test(d)){var j=d.match(T);if(j){var _=j[2]-1||0,H=(j[7]||"0").substring(0,3);return M?new Date(Date.UTC(j[1],_,j[3]||1,j[4]||0,j[5]||0,j[6]||0,H)):new Date(j[1],_,j[3]||1,j[4]||0,j[5]||0,j[6]||0,H)}}return new Date(d)}(c),this.init()},h.init=function(){var c=this.$d;this.$y=c.getFullYear(),this.$M=c.getMonth(),this.$D=c.getDate(),this.$W=c.getDay(),this.$H=c.getHours(),this.$m=c.getMinutes(),this.$s=c.getSeconds(),this.$ms=c.getMilliseconds()},h.$utils=function(){return O},h.isValid=function(){return this.$d.toString()!==a},h.isSame=function(c,b){var d=N(c);return this.startOf(b)<=d&&d<=this.endOf(b)},h.isAfter=function(c,b){return N(c){(function(e,t){typeof Ye=="object"&&typeof Ce<"u"?Ce.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_duration=t()})(Ye,function(){"use strict";var e,t,r=1e3,n=6e4,i=36e5,u=864e5,s=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,f=31536e6,w=2628e6,g=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/,l={years:f,months:w,days:u,hours:i,minutes:n,seconds:r,milliseconds:1,weeks:6048e5},x=function(S){return S instanceof F},v=function(S,p,o){return new F(S,o,p.$l)},a=function(S){return t.p(S)+"s"},T=function(S){return S<0},E=function(S){return T(S)?Math.ceil(S):Math.floor(S)},I=function(S){return Math.abs(S)},Y=function(S,p){return S?T(S)?{negative:!0,format:""+I(S)+p}:{negative:!1,format:""+S+p}:{negative:!1,format:""}},F=function(){function S(o,D,N){var O=this;if(this.$d={},this.$l=N,o===void 0&&(this.$ms=0,this.parseFromMilliseconds()),D)return v(o*l[a(D)],this);if(typeof o=="number")return this.$ms=o,this.parseFromMilliseconds(),this;if(typeof o=="object")return Object.keys(o).forEach(function($){O.$d[a($)]=o[$]}),this.calMilliseconds(),this;if(typeof o=="string"){var B=o.match(g);if(B){var J=B.slice(2).map(function($){return $!=null?Number($):0});return this.$d.years=J[0],this.$d.months=J[1],this.$d.weeks=J[2],this.$d.days=J[3],this.$d.hours=J[4],this.$d.minutes=J[5],this.$d.seconds=J[6],this.calMilliseconds(),this}}return this}var p=S.prototype;return p.calMilliseconds=function(){var o=this;this.$ms=Object.keys(this.$d).reduce(function(D,N){return D+(o.$d[N]||0)*l[N]},0)},p.parseFromMilliseconds=function(){var o=this.$ms;this.$d.years=E(o/f),o%=f,this.$d.months=E(o/w),o%=w,this.$d.days=E(o/u),o%=u,this.$d.hours=E(o/i),o%=i,this.$d.minutes=E(o/n),o%=n,this.$d.seconds=E(o/r),o%=r,this.$d.milliseconds=o},p.toISOString=function(){var o=Y(this.$d.years,"Y"),D=Y(this.$d.months,"M"),N=+this.$d.days||0;this.$d.weeks&&(N+=7*this.$d.weeks);var O=Y(N,"D"),B=Y(this.$d.hours,"H"),J=Y(this.$d.minutes,"M"),$=this.$d.seconds||0;this.$d.milliseconds&&($+=this.$d.milliseconds/1e3,$=Math.round(1e3*$)/1e3);var h=Y($,"S"),c=o.negative||D.negative||O.negative||B.negative||J.negative||h.negative,b=B.format||J.format||h.format?"T":"",d=(c?"-":"")+"P"+o.format+D.format+O.format+b+B.format+J.format+h.format;return d==="P"||d==="-P"?"P0D":d},p.toJSON=function(){return this.toISOString()},p.format=function(o){var D=o||"YYYY-MM-DDTHH:mm:ss",N={Y:this.$d.years,YY:t.s(this.$d.years,2,"0"),YYYY:t.s(this.$d.years,4,"0"),M:this.$d.months,MM:t.s(this.$d.months,2,"0"),D:this.$d.days,DD:t.s(this.$d.days,2,"0"),H:this.$d.hours,HH:t.s(this.$d.hours,2,"0"),m:this.$d.minutes,mm:t.s(this.$d.minutes,2,"0"),s:this.$d.seconds,ss:t.s(this.$d.seconds,2,"0"),SSS:t.s(this.$d.milliseconds,3,"0")};return D.replace(s,function(O,B){return B||String(N[O])})},p.as=function(o){return this.$ms/l[a(o)]},p.get=function(o){var D=this.$ms,N=a(o);return N==="milliseconds"?D%=1e3:D=N==="weeks"?E(D/l[N]):this.$d[N],D||0},p.add=function(o,D,N){var O;return O=D?o*l[a(D)]:x(o)?o.$ms:v(o,this).$ms,v(this.$ms+O*(N?-1:1),this)},p.subtract=function(o,D){return this.add(o,D,!0)},p.locale=function(o){var D=this.clone();return D.$l=o,D},p.clone=function(){return v(this.$ms,this)},p.humanize=function(o){return e().add(this.$ms,"ms").locale(this.$l).fromNow(!o)},p.valueOf=function(){return this.asMilliseconds()},p.milliseconds=function(){return this.get("milliseconds")},p.asMilliseconds=function(){return this.as("milliseconds")},p.seconds=function(){return this.get("seconds")},p.asSeconds=function(){return this.as("seconds")},p.minutes=function(){return this.get("minutes")},p.asMinutes=function(){return this.as("minutes")},p.hours=function(){return this.get("hours")},p.asHours=function(){return this.as("hours")},p.days=function(){return this.get("days")},p.asDays=function(){return this.as("days")},p.weeks=function(){return this.get("weeks")},p.asWeeks=function(){return this.as("weeks")},p.months=function(){return this.get("months")},p.asMonths=function(){return this.as("months")},p.years=function(){return this.get("years")},p.asYears=function(){return this.as("years")},S}(),q=function(S,p,o){return S.add(p.years()*o,"y").add(p.months()*o,"M").add(p.days()*o,"d").add(p.hours()*o,"h").add(p.minutes()*o,"m").add(p.seconds()*o,"s").add(p.milliseconds()*o,"ms")};return function(S,p,o){e=o,t=o().$utils(),o.duration=function(O,B){var J=o.locale();return v(O,{$l:J},B)},o.isDuration=x;var D=p.prototype.add,N=p.prototype.subtract;p.prototype.add=function(O,B){return x(O)?q(this,O,1):D.bind(this)(O,B)},p.prototype.subtract=function(O,B){return x(O)?q(this,O,-1):N.bind(this)(O,B)}}})});var vt=U((Ee,Ie)=>{(function(e,t){typeof Ee=="object"&&typeof Ie<"u"?Ie.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_advancedFormat=t()})(Ee,function(){"use strict";return function(e,t){var r=t.prototype,n=r.format;r.format=function(i){var u=this,s=this.$locale();if(!this.isValid())return n.bind(this)(i);var f=this.$utils(),w=(i||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(g){switch(g){case"Q":return Math.ceil((u.$M+1)/3);case"Do":return s.ordinal(u.$D);case"gggg":return u.weekYear();case"GGGG":return u.isoWeekYear();case"wo":return s.ordinal(u.week(),"W");case"w":case"ww":return f.s(u.week(),g==="w"?1:2,"0");case"W":case"WW":return f.s(u.isoWeek(),g==="W"?1:2,"0");case"k":case"kk":return f.s(String(u.$H===0?24:u.$H),g==="k"?1:2,"0");case"X":return Math.floor(u.$d.getTime()/1e3);case"x":return u.$d.getTime();case"z":return"["+u.offsetName()+"]";case"zzz":return"["+u.offsetName("long")+"]";default:return g}});return n.bind(this)(w)}}})});var $t=U((_e,We)=>{(function(e,t){typeof _e=="object"&&typeof We<"u"?We.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_isoWeek=t()})(_e,function(){"use strict";var e="day";return function(t,r,n){var i=function(f){return f.add(4-f.isoWeekday(),e)},u=r.prototype;u.isoWeekYear=function(){return i(this).year()},u.isoWeek=function(f){if(!this.$utils().u(f))return this.add(7*(f-this.isoWeek()),e);var w,g,l,x,v=i(this),a=(w=this.isoWeekYear(),g=this.$u,l=(g?n.utc:n)().year(w).startOf("year"),x=4-l.isoWeekday(),l.isoWeekday()>4&&(x+=7),l.add(x,e));return v.diff(a,"week")+1},u.isoWeekday=function(f){return this.$utils().u(f)?this.day()||7:this.day(this.day()%7?f:f-7)};var s=u.startOf;u.startOf=function(f,w){var g=this.$utils(),l=!!g.u(w)||w;return g.p(f)==="isoweek"?l?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):s.bind(this)(f,w)}}})});var bt=U((Fe,He)=>{(function(e,t){typeof Fe=="object"&&typeof He<"u"?He.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_weekYear=t()})(Fe,function(){"use strict";return function(e,t){t.prototype.weekYear=function(){var r=this.month(),n=this.week(),i=this.year();return n===1&&r===11?i+1:r===0&&n>=52?i-1:i}}})});var wt=U((Be,Le)=>{(function(e,t){typeof Be=="object"&&typeof Le<"u"?Le.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_weekOfYear=t()})(Be,function(){"use strict";var e="week",t="year";return function(r,n,i){var u=n.prototype;u.week=function(s){if(s===void 0&&(s=null),s!==null)return this.add(7*(s-this.week()),"day");var f=this.$locale().yearStart||1;if(this.month()===11&&this.date()>25){var w=i(this).startOf(t).add(1,t).date(f),g=i(this).endOf(e);if(w.isBefore(g))return 1}var l=i(this).startOf(t).date(f).startOf(e).subtract(1,"millisecond"),x=this.diff(l,e,!0);return x<0?i(this).startOf("week").week():Math.ceil(x)},u.weeks=function(s){return s===void 0&&(s=null),this.week(s)}}})});var Ot=U((ze,Pe)=>{(function(e,t){typeof ze=="object"&&typeof Pe<"u"?Pe.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_relativeTime=t()})(ze,function(){"use strict";return function(e,t,r){e=e||{};var n=t.prototype,i={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function u(f,w,g,l){return n.fromToBase(f,w,g,l)}r.en.relativeTime=i,n.fromToBase=function(f,w,g,l,x){for(var v,a,T,E=g.$locale().relativeTime||i,I=e.thresholds||[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],Y=I.length,F=0;F0,S<=q.r||!q.r){S<=1&&F>0&&(q=I[F-1]);var p=E[q.l];x&&(S=x(""+S)),a=typeof p=="string"?p.replace("%d",S):p(S,w,q.l,T);break}}if(w)return a;var o=T?E.future:E.past;return typeof o=="function"?o(a):o.replace("%s",a)},n.to=function(f,w){return u(f,w,this,!0)},n.from=function(f,w){return u(f,w,this)};var s=function(f){return f.$u?r.utc():r()};n.toNow=function(f){return this.to(s(this),f)},n.fromNow=function(f){return this.from(s(this),f)}}})});var xt=U((Re,Je)=>{(function(e,t){typeof Re=="object"&&typeof Je<"u"?Je.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_utc=t()})(Re,function(){"use strict";var e="minute",t=/[+-]\d\d(?::?\d\d)?/g,r=/([+-]|\d\d)/g;return function(n,i,u){var s=i.prototype;u.utc=function(a){var T={date:a,utc:!0,args:arguments};return new i(T)},s.utc=function(a){var T=u(this.toDate(),{locale:this.$L,utc:!0});return a?T.add(this.utcOffset(),e):T},s.local=function(){return u(this.toDate(),{locale:this.$L,utc:!1})};var f=s.parse;s.parse=function(a){a.utc&&(this.$u=!0),this.$utils().u(a.$offset)||(this.$offset=a.$offset),f.call(this,a)};var w=s.init;s.init=function(){if(this.$u){var a=this.$d;this.$y=a.getUTCFullYear(),this.$M=a.getUTCMonth(),this.$D=a.getUTCDate(),this.$W=a.getUTCDay(),this.$H=a.getUTCHours(),this.$m=a.getUTCMinutes(),this.$s=a.getUTCSeconds(),this.$ms=a.getUTCMilliseconds()}else w.call(this)};var g=s.utcOffset;s.utcOffset=function(a,T){var E=this.$utils().u;if(E(a))return this.$u?0:E(this.$offset)?g.call(this):this.$offset;if(typeof a=="string"&&(a=function(q){q===void 0&&(q="");var S=q.match(t);if(!S)return null;var p=(""+S[0]).match(r)||["-",0,0],o=p[0],D=60*+p[1]+ +p[2];return D===0?0:o==="+"?D:-D}(a),a===null))return this;var I=Math.abs(a)<=16?60*a:a,Y=this;if(T)return Y.$offset=I,Y.$u=a===0,Y;if(a!==0){var F=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();(Y=this.local().add(I+F,e)).$offset=I,Y.$x.$localOffset=F}else Y=this.utc();return Y};var l=s.format;s.format=function(a){var T=a||(this.$u?"YYYY-MM-DDTHH:mm:ss[Z]":"");return l.call(this,T)},s.valueOf=function(){var a=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*a},s.isUTC=function(){return!!this.$u},s.toISOString=function(){return this.toDate().toISOString()},s.toString=function(){return this.toDate().toUTCString()};var x=s.toDate;s.toDate=function(a){return a==="s"&&this.$offset?u(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate():x.call(this)};var v=s.diff;s.diff=function(a,T,E){if(a&&this.$u===a.$u)return v.call(this,a,T,E);var I=this.local(),Y=u(a).local();return v.call(I,Y,T,E)}}})});var St=U((Ge,Ze)=>{(function(e,t){typeof Ge=="object"&&typeof Ze<"u"?Ze.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_timezone=t()})(Ge,function(){"use strict";var e={year:0,month:1,day:2,hour:3,minute:4,second:5},t={};return function(r,n,i){var u,s=function(l,x,v){v===void 0&&(v={});var a=new Date(l),T=function(E,I){I===void 0&&(I={});var Y=I.timeZoneName||"short",F=E+"|"+Y,q=t[F];return q||(q=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:E,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:Y}),t[F]=q),q}(x,v);return T.formatToParts(a)},f=function(l,x){for(var v=s(l,x),a=[],T=0;T=0&&(a[F]=parseInt(Y,10))}var q=a[3],S=q===24?0:q,p=a[0]+"-"+a[1]+"-"+a[2]+" "+S+":"+a[4]+":"+a[5]+":000",o=+l;return(i.utc(p).valueOf()-(o-=o%1e3))/6e4},w=n.prototype;w.tz=function(l,x){l===void 0&&(l=u);var v=this.utcOffset(),a=this.toDate(),T=a.toLocaleString("en-US",{timeZone:l}),E=Math.round((a-new Date(T))/1e3/60),I=i(T,{locale:this.$L}).$set("millisecond",this.$ms).utcOffset(15*-Math.round(a.getTimezoneOffset()/15)-E,!0);if(x){var Y=I.utcOffset();I=I.add(v-Y,"minute")}return I.$x.$timezone=l,I},w.offsetName=function(l){var x=this.$x.$timezone||i.tz.guess(),v=s(this.valueOf(),x,{timeZoneName:l}).find(function(a){return a.type.toLowerCase()==="timezonename"});return v&&v.value};var g=w.startOf;w.startOf=function(l,x){if(!this.$x||!this.$x.$timezone)return g.call(this,l,x);var v=i(this.format("YYYY-MM-DD HH:mm:ss:SSS"),{locale:this.$L});return g.call(v,l,x).tz(this.$x.$timezone,!0)},i.tz=function(l,x,v){var a=v&&x,T=v||x||u,E=f(+i(),T);if(typeof l!="string")return i(l).tz(T);var I=function(S,p,o){var D=S-60*p*1e3,N=f(D,o);if(p===N)return[D,p];var O=f(D-=60*(N-p)*1e3,o);return N===O?[D,N]:[S-60*Math.min(N,O)*1e3,Math.max(N,O)]}(i.utc(l,a).valueOf(),E,T),Y=I[0],F=I[1],q=i(Y).utcOffset(F);return q.$x.$timezone=T,q},i.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},i.tz.setDefault=function(l){u=l}}})});var Mt=U((ji,Ke)=>{var X=gt();X.extend(yt());X.extend(vt());X.extend($t());X.extend(bt());X.extend(wt());X.extend(Ot());X.extend(xt());X.extend(St());function fe(e){return typeof e=="object"&&typeof e.hash=="object"}function Ve(e){return typeof e=="object"&&typeof e.options=="object"&&typeof e.app=="object"}function Qe(e,t,r){if(fe(e))return Qe({},t,e);if(fe(t))return Qe(e,r,t);let n=Ve(e)?e.context:{};r=r||{},fe(r)||(t=Object.assign({},t,r)),fe(r)&&r.hash.root===!0&&(t=Object.assign({},r.data.root,t));let i=Object.assign({},n,t,r.hash);return Ve(e)||(i=Object.assign({},e,i)),Ve(e)&&e.view&&e.view.data&&(i=Object.assign({},i,e.view.data)),i}function Xe(e,t,r){return fe(t)&&(r=t,t=null),fe(e)&&(r=e,t=null,e=null),{str:e,pattern:t,options:r}}function Nt(e,t,r){let n=Xe(e,t,r),i={lang:"en",date:new Date(n.str)},u=Qe(this,i,{});X.locale(u.lang||u.language)}Ke.exports.date=(e,t,r)=>{let n=Xe(e,t,r);if(n.str==null&&n.pattern==null)return X.locale("en"),X().format("MMMM DD, YYYY");Nt(n.str,n.pattern,n.options);let i=X(new Date(n.str));return typeof n.options=="string"?i=n.options.toLowerCase()==="utc"?i.utc():i.tz(n.options):i=i.tz(X.tz.guess()),n.pattern===""?i.toISOString():i.format(n.pattern)};Ke.exports.duration=(e,t,r)=>{let n=Xe(e,t);Nt(n.str,n.pattern);let i=X.duration(n.str,n.pattern);return r&&!fe(r)?i.format(r):i.humanize()}});var et=U((Ai,At)=>{At.exports=function(e){return e!=null&&(jt(e)||ln(e)||!!e._isBuffer)};function jt(e){return!!e.constructor&&typeof e.constructor.isBuffer=="function"&&e.constructor.isBuffer(e)}function ln(e){return typeof e.readFloatLE=="function"&&typeof e.slice=="function"&&jt(e.slice(0,0))}});var Dt=U((ki,kt)=>{var dn=et(),hn=Object.prototype.toString;kt.exports=function(t){if(typeof t>"u")return"undefined";if(t===null)return"null";if(t===!0||t===!1||t instanceof Boolean)return"boolean";if(typeof t=="string"||t instanceof String)return"string";if(typeof t=="number"||t instanceof Number)return"number";if(typeof t=="function"||t instanceof Function)return"function";if(typeof Array.isArray<"u"&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var r=hn.call(t);return r==="[object RegExp]"?"regexp":r==="[object Date]"?"date":r==="[object Arguments]"?"arguments":r==="[object Error]"?"error":dn(t)?"buffer":r==="[object Set]"?"set":r==="[object WeakSet]"?"weakset":r==="[object Map]"?"map":r==="[object WeakMap]"?"weakmap":r==="[object Symbol]"?"symbol":r==="[object Int8Array]"?"int8array":r==="[object Uint8Array]"?"uint8array":r==="[object Uint8ClampedArray]"?"uint8clampedarray":r==="[object Int16Array]"?"int16array":r==="[object Uint16Array]"?"uint16array":r==="[object Int32Array]"?"int32array":r==="[object Uint32Array]"?"uint32array":r==="[object Float32Array]"?"float32array":r==="[object Float64Array]"?"float64array":"object"}});var Yt=U((Di,qt)=>{"use strict";var Ut=Dt(),Tt={arguments:"an arguments object",array:"an array",boolean:"a boolean",buffer:"a buffer",date:"a date",error:"an error",float32array:"a float32array",float64array:"a float64array",function:"a function",int16array:"an int16array",int32array:"an int32array",int8array:"an int8array",map:"a Map",null:"null",number:"a number",object:"an object",regexp:"a regular expression",set:"a Set",string:"a string",symbol:"a symbol",uint16array:"an uint16array",uint32array:"an uint32array",uint8array:"an uint8array",uint8clampedarray:"an uint8clampedarray",undefined:"undefined",weakmap:"a WeakMap",weakset:"a WeakSet"};function tt(e){return Tt[Ut(e)]}tt.types=Tt;tt.typeOf=Ut;qt.exports=tt});var xe=U((Ui,Et)=>{var pn=Object.prototype.toString;Et.exports=function(t){if(t===void 0)return"undefined";if(t===null)return"null";var r=typeof t;if(r==="boolean")return"boolean";if(r==="string")return"string";if(r==="number")return"number";if(r==="symbol")return"symbol";if(r==="function")return $n(t)?"generatorfunction":"function";if(mn(t))return"array";if(On(t))return"buffer";if(wn(t))return"arguments";if(yn(t))return"date";if(gn(t))return"error";if(vn(t))return"regexp";switch(Ct(t)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(bn(t))return"generator";switch(r=pn.call(t),r){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return r.slice(8,-1).toLowerCase().replace(/\s/g,"")};function Ct(e){return typeof e.constructor=="function"?e.constructor.name:null}function mn(e){return Array.isArray?Array.isArray(e):e instanceof Array}function gn(e){return e instanceof Error||typeof e.message=="string"&&e.constructor&&typeof e.constructor.stackTraceLimit=="number"}function yn(e){return e instanceof Date?!0:typeof e.toDateString=="function"&&typeof e.getDate=="function"&&typeof e.setDate=="function"}function vn(e){return e instanceof RegExp?!0:typeof e.flags=="string"&&typeof e.ignoreCase=="boolean"&&typeof e.multiline=="boolean"&&typeof e.global=="boolean"}function $n(e,t){return Ct(e)==="GeneratorFunction"}function bn(e){return typeof e.throw=="function"&&typeof e.return=="function"&&typeof e.next=="function"}function wn(e){try{if(typeof e.length=="number"&&typeof e.callee=="function")return!0}catch(t){if(t.message.indexOf("callee")!==-1)return!0}return!1}function On(e){return e.constructor&&typeof e.constructor.isBuffer=="function"?e.constructor.isBuffer(e):!1}});var ee=U((Wt,Ft)=>{"use strict";var xn=Ue("util"),It=Yt(),Sn=xe(),m=Wt=Ft.exports;m.extend=_t;m.indexOf=Dn;m.escapeExpression=Un;m.isEmpty=Cn;m.createFrame=Tn;m.blockParams=qn;m.appendContextPath=Yn;var Nn={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`","=":"="},Mn=/[&<>"'`=]/g,jn=/[&<>"'`=]/;function An(e){return Nn[e]}function _t(e){for(var t=1;t{"use strict";var En=ee();he.contains=function(e,t,r){return e==null||t==null||isNaN(e.length)?!1:e.indexOf(t,r)!==-1};he.chop=function(e){if(typeof e!="string")return"";var t=/^[-_.\W\s]+|[-_.\W\s]+$/g;return e.trim().replace(t,"")};he.changecase=function(e,t){if(typeof e!="string")return"";if(e.length===1)return e.toLowerCase();e=he.chop(e).toLowerCase(),typeof t!="function"&&(t=En.identity);var r=/[-_.\W\s]+(\w|$)/g;return e.replace(r,function(n,i){return t(i)})};he.random=function(e,t){return e+Math.floor(Math.random()*(t-e+1))}});var Bt=U((qi,Ht)=>{"use strict";var In=Se(),V=Ht.exports;V.abs=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.abs(e)};V.add=function(e,t){return!isNaN(e)&&!isNaN(t)?Number(e)+Number(t):typeof e=="string"&&typeof t=="string"?e+t:""};V.avg=function(){let e=[].concat.apply([],arguments);return e.pop(),V.sum(e)/e.length};V.ceil=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.ceil(e)};V.divide=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)/Number(t)};V.floor=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.floor(e)};V.minus=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)-Number(t)};V.modulo=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)%Number(t)};V.multiply=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)*Number(t)};V.plus=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)+Number(t)};V.random=function(e,t){if(isNaN(e))throw new TypeError("expected minimum to be a number");if(isNaN(t))throw new TypeError("expected maximum to be a number");return In.random(e,t)};V.remainder=function(e,t){return e%t};V.round=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.round(e)};V.subtract=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)-Number(t)};V.sum=function(){for(var e=[].concat.apply([],arguments),t=e.length,r=0;t--;)isNaN(e[t])||(r+=Number(e[t]));return r}});var zt=U((Yi,Lt)=>{"use strict";Lt.exports=function(t){return t!=null&&typeof t=="object"&&Array.isArray(t)===!1}});var Ne=U((Ci,Gt)=>{var Jt=zt();Gt.exports=function(e,t,r){if(Jt(r)||(r={default:r}),!Rt(e))return typeof r.default<"u"?r.default:e;typeof t=="number"&&(t=String(t));let n=Array.isArray(t),i=typeof t=="string",u=r.separator||".",s=r.joinChar||(typeof u=="string"?u:".");if(!i&&!n)return e;if(i&&t in e)return it(t,e,r)?e[t]:r.default;let f=n?t:_n(t,u,r),w=f.length,g=0;do{let l=f[g];for(typeof l=="number"&&(l=String(l));l&&l.slice(-1)==="\\";)l=Pt([l.slice(0,-1),f[++g]||""],s,r);if(l in e){if(!it(l,e,r))return r.default;e=e[l]}else{let x=!1,v=g+1;for(;v{"use strict";Zt.exports=function(t){if(typeof t!="object")throw new TypeError("createFrame expects data to be an object");var r=Object.assign({},t);if(r._parent=t,r.extend=function(s){Object.assign(this,s)},arguments.length>1)for(var n=[].slice.call(arguments,1),i=n.length,u=-1;++u{"use strict";var y=ee(),C=Vt.exports,oe=Ne(),Wn=ut();C.after=function(e,t){return y.isUndefined(e)?"":(e=y.result(e),Array.isArray(e)?e.slice(t):"")};C.arrayify=function(e){return y.isUndefined(e)?[]:e?Array.isArray(e)?e:[e]:[]};C.before=function(e,t){return y.isUndefined(e)?"":(e=y.result(e),Array.isArray(e)?e.slice(0,t-1):"")};C.eachIndex=function(e,t){var r="";if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e))for(var n=0;n0){for(var s=0;s-1,this,r):"")};C.isArray=function(e){return Array.isArray(e)};C.itemAt=function(e,t){if(y.isUndefined(e))return null;if(e=y.result(e),Array.isArray(e)){if(t=isNaN(t)?0:+t,t<0)return e[e.length+t];if(ti[t]>u[t]?1:-1)}return""};C.withAfter=function(e,t,r){if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e)){e=e.slice(t);for(var n="",i=0;i0){for(var i=[],u=0;u0&&u%t===0&&(n+=r.fn(i),i=[]),i.push(e[u]);n+=r.fn(i)}return n};C.withLast=function(e,t,r){if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e)){if(y.isUndefined(t)||(t=parseFloat(y.result(t))),y.isUndefined(t))return r=t,r.fn(e[e.length-1]);e=e.slice(-t);for(var n=e.length,i=-1,u="";++ig?1:w{"use strict";var Qt=ee(),te=Xt.exports;te.bytes=function(e,t,r){if(e==null||isNaN(e)&&(e=e.length,!e))return"0 B";isNaN(t)&&(t=2);var n=["B","kB","MB","GB","TB","PB","EB","ZB","YB"];t=Math.pow(10,t),e=Number(e);for(var i=n.length-1;i-->=0;){var u=Math.pow(10,i*3);if(u<=e+1){e=Math.round(e*t/u)/t,e+=" "+n[i];break}}return e};te.addCommas=function(e){return e.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,")};te.phoneNumber=function(e){return e=e.toString(),"("+e.substr(0,3)+") "+e.substr(3,3)+"-"+e.substr(6,4)};te.toAbbr=function(e,t){isNaN(e)&&(e=0),Qt.isUndefined(t)&&(t=2),e=Number(e),t=Math.pow(10,t);for(var r=["k","m","b","t","q"],n=r.length-1;n>=0;){var i=Math.pow(10,(n+1)*3);if(i<=e+1){e=Math.round(e*t/i)/t,e+=r[n];break}n--}return e};te.toExponential=function(e,t){return isNaN(e)&&(e=0),Qt.isUndefined(t)&&(t=0),Number(e).toExponential(t)};te.toFixed=function(e,t){return isNaN(e)&&(e=0),isNaN(t)&&(t=0),Number(e).toFixed(t)};te.toFloat=function(e){return parseFloat(e)};te.toInt=function(e){return parseInt(e,10)};te.toPrecision=function(e,t){return isNaN(e)&&(e=0),isNaN(t)&&(t=1),Number(e).toPrecision(t)}});var tr=U((Wi,er)=>{"use strict";var st=Ue("url"),ge=ee(),Fn=Ue("querystring"),ae=er.exports;ae.encodeURI=function(e){if(ge.isString(e))return encodeURIComponent(e)};ae.escape=function(e){if(ge.isString(e))return Fn.escape(e)};ae.decodeURI=function(e){if(ge.isString(e))return decodeURIComponent(e)};ae.urlResolve=function(e,t){return st.resolve(e,t)};ae.urlParse=function(e){return st.parse(e)};ae.stripQuerystring=function(e){if(ge.isString(e))return e.split("?")[0]};ae.stripProtocol=function(e){if(ge.isString(e)){var t=st.parse(e);return t.protocol="",t.format()}}});var ir=U((rr,nr)=>{"use strict";var z=ee(),ce=Se(),A=nr.exports;A.append=function(e,t){return typeof e=="string"&&typeof t=="string"?e+t:e};A.camelcase=function(e){return typeof e!="string"?"":ce.changecase(e,function(t){return t.toUpperCase()})};A.capitalize=function(e){return typeof e!="string"?"":e.charAt(0).toUpperCase()+e.slice(1)};A.capitalizeAll=function(e){if(typeof e!="string")return"";if(z.isString(e))return e.replace(/\w\S*/g,function(t){return A.capitalize(t)})};A.center=function(e,t){if(typeof e!="string")return"";for(var r="",n=0;n-1;)i++,n+=r;return i};A.pascalcase=function(e){return typeof e!="string"?"":(e=ce.changecase(e,function(t){return t.toUpperCase()}),e.charAt(0).toUpperCase()+e.slice(1))};A.pathcase=function(e){return typeof e!="string"?"":ce.changecase(e,function(t){return"/"+t})};A.plusify=function(e,t){return typeof e!="string"?"":(z.isString(t)||(t=" "),e.split(t).join("+"))};A.prepend=function(e,t){return typeof e=="string"&&typeof t=="string"?t+e:e};A.raw=function(e){var t=e.fn(),r=z.options(this,e);if(r.escape!==!1)for(var n=0;(n=t.indexOf("{{",n))!==-1;)t[n-1]!=="\\"&&(t=t.slice(0,n)+"\\"+t.slice(n)),n+=3;return t};A.remove=function(e,t){return typeof e!="string"?"":z.isString(t)?e.split(t).join(""):e};A.removeFirst=function(e,t){return typeof e!="string"?"":z.isString(t)?e.replace(t,""):e};A.replace=function(e,t,r){return typeof e!="string"?"":z.isString(t)?(z.isString(r)||(r=""),e.split(t).join(r)):e};A.replaceFirst=function(e,t,r){return typeof e!="string"?"":z.isString(t)?(z.isString(r)||(r=""),e.replace(t,r)):e};A.reverse=Me().reverse;A.sentence=function(e){return typeof e!="string"?"":e.replace(/((?:\S[^\.\?\!]*)[\.\?\!]*)/g,function(t){return t.charAt(0).toUpperCase()+t.substr(1).toLowerCase()})};A.snakecase=function(e){return typeof e!="string"?"":ce.changecase(e,function(t){return"_"+t})};A.split=function(e,t){return typeof e!="string"?"":(z.isString(t)||(t=","),e.split(t))};A.startsWith=function(e,t,r){var n=[].slice.call(arguments);return r=n.pop(),z.isString(t)&&t.indexOf(e)===0?r.fn(this):typeof r.inverse=="function"?r.inverse(this):""};A.titleize=function(e){if(typeof e!="string")return"";for(var t=e.replace(/[- _]+/g," "),r=t.split(" "),n=r.length,i=[],u=0;n--;){var s=r[u++];i.push(rr.capitalize(s))}return i.join(" ")};A.trim=function(e){return typeof e=="string"?e.trim():""};A.trimLeft=function(e){if(z.isString(e))return e.replace(/^\s+/,"")};A.trimRight=function(e){if(z.isString(e))return e.replace(/\s+$/,"")};A.truncate=function(e,t,r){if(z.isString(e))return typeof r!="string"&&(r=""),e.length>t?e.slice(0,t-r.length)+r:e};A.truncateWords=function(e,t,r){if(z.isString(e)&&!isNaN(t)){typeof r!="string"&&(r="\u2026");var n=Number(t),i=e.split(/[ \t]/);if(n>=i.length)return e;i=i.slice(0,n);var u=i.join(" ").trim();return u+r}};A.upcase=function(){return A.uppercase.apply(this,arguments)};A.uppercase=function(e){return z.isObject(e)&&e.fn?e.fn(this).toUpperCase():typeof e!="string"?"":e.toUpperCase()}});var sr=U((Fi,ur)=>{"use strict";var Hn=xe();ur.exports=function e(t){switch(Hn(t)){case"boolean":case"date":case"function":case"null":case"number":return!0;case"undefined":return!1;case"regexp":return t.source!=="(?:)"&&t.source!=="";case"buffer":return t.toString()!=="";case"error":return t.message!=="";case"string":case"arguments":return t.length!==0;case"file":case"map":case"set":return t.size!==0;case"array":case"object":for(let r of Object.keys(t))if(e(t[r]))return!0;return!1;default:return!0}}});var or=U((Hi,fr)=>{"use strict";var Bn=Ne(),Ln=sr();fr.exports=function(e,t,r){return zn(e)&&(typeof t=="string"||Array.isArray(t))?Ln(Bn(e,t,r)):!1};function zn(e){return e!=null&&(typeof e=="object"||typeof e=="function"||Array.isArray(e))}});var cr=U((Bi,ar)=>{"use strict";function ft(e,t){if(!e)return!0;let r=t||ft.keywords;Array.isArray(r)||(r=[r]);let n=typeof e=="string"?e.toLowerCase():null;for(let i of r)if(i===e||i===n)return!0;return!1}ft.keywords=["0","false","nada","nil","nay","nah","negative","no","none","nope","nul","null","nix","nyet","uh-uh","veto","zero"];ar.exports=ft});var dr=U((Li,lr)=>{"use strict";lr.exports=function(t){let r=Math.abs(t);if(isNaN(r))throw new TypeError("expected a number");if(!Number.isInteger(r))throw new Error("expected an integer");if(!Number.isSafeInteger(r))throw new Error("value exceeds maximum safe integer");return r%2===1}});var gr=U((zi,mr)=>{"use strict";var Pn=or(),k=ee(),Rn=Se(),hr=cr(),pr=dr(),W=mr.exports;W.and=function(){for(var e=arguments.length-1,t=arguments[e],r=!0,n=0;n":i=e>r;break;case"<=":i=e<=r;break;case">=":i=e>=r;break;case"typeof":i=typeof e===r;break;default:throw new Error("helper {{compare}}: invalid operator: `"+t+"`")}return k.value(i,this,n)};W.contains=function(e,t,r,n){typeof r=="object"&&(n=r,r=void 0);var i=Rn.contains(e,t,r);return k.value(i,this,n)};W.default=function(){for(var e=0;et,this,r)};W.gte=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e>=t,this,r)};W.has=function(e,t,r){return k.isOptions(e)&&(r=e,t=null,e=null),k.isOptions(t)&&(r=t,t=null),e===null?k.value(!1,this,r):arguments.length===2?k.value(Pn(this,e),this,r):(Array.isArray(e)||k.isString(e))&&k.isString(t)&&e.indexOf(t)>-1?k.fn(!0,this,r):k.isObject(e)&&k.isString(t)&&t in e?k.fn(!0,this,r):k.inverse(!1,this,r)};W.isFalsey=function(e,t){return k.value(hr(e),this,t)};W.isTruthy=function(e,t){return k.value(!hr(e),this,t)};W.ifEven=function(e,t){return k.value(!pr(e),this,t)};W.ifNth=function(e,t,r){var n=!isNaN(e)&&!isNaN(t)&&t%e===0;return k.value(n,this,r)};W.ifOdd=function(e,t){return k.value(pr(e),this,t)};W.is=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e==t,this,r)};W.isnt=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e!=t,this,r)};W.lt=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e=t,this,r)};W.unlessGteq=function(e,t,r){return k.isOptions(t)&&(r=t,t=r.hash.compare),k.value(et,this,r)}});var vr=U((Pi,yr)=>{var Jn=et(),Gn=Object.prototype.toString;yr.exports=function(t){if(typeof t>"u")return"undefined";if(t===null)return"null";if(t===!0||t===!1||t instanceof Boolean)return"boolean";if(typeof t=="string"||t instanceof String)return"string";if(typeof t=="number"||t instanceof Number)return"number";if(typeof t=="function"||t instanceof Function)return"function";if(typeof Array.isArray<"u"&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var r=Gn.call(t);return r==="[object RegExp]"?"regexp":r==="[object Date]"?"date":r==="[object Arguments]"?"arguments":r==="[object Error]"?"error":Jn(t)?"buffer":r==="[object Set]"?"set":r==="[object WeakSet]"?"weakset":r==="[object Map]"?"map":r==="[object WeakMap]"?"weakmap":r==="[object Symbol]"?"symbol":r==="[object Int8Array]"?"int8array":r==="[object Uint8Array]"?"uint8array":r==="[object Uint8ClampedArray]"?"uint8clampedarray":r==="[object Int16Array]"?"int16array":r==="[object Uint16Array]"?"uint16array":r==="[object Int32Array]"?"int32array":r==="[object Uint32Array]"?"uint32array":r==="[object Float32Array]"?"float32array":r==="[object Float64Array]"?"float64array":"object"}});var br=U((Ri,$r)=>{"use strict";var Zn=vr();$r.exports=function(t){var r=Zn(t);if(r!=="number"&&r!=="string")return!1;var n=+t;return n-n+1>=0&&t!==""}});var Or=U((Ji,wr)=>{"use strict";var Vn=br();wr.exports=function(t,r){if(!r)return t;if(!t)return{};for(var n=String(r).split(/[[.\]]/).filter(Boolean),i=n[n.length-1],u={};r=n.shift();)if(t=t[r],!t)return{};return Vn(i)?[t]:(u[i]=t,u)}});var Mr=U((Gi,Nr)=>{"use strict";var Qn=Object.hasOwnProperty,ye=ee(),Xn=Me(),P=Nr.exports,Kn=Ne(),xr=Or(),Sr=ut();P.extend=function(){var e=[].slice.call(arguments),t={};ye.isOptions(e[e.length-1])&&(t=e.pop().hash,e.push(t));for(var r={},n=0;n{"use strict";var ei=ee(),jr=Ar.exports,ti=xe();jr.toRegex=function(e,t,r){var n=ei.options({},t,r);return new RegExp(e,n.flags)};jr.test=function(e,t){if(typeof e!="string")return!1;if(ti(t)!=="regexp")throw new TypeError("expected a regular expression");return t.test(e)}});import ri from"crypto";function ve(){return je>Ae.length-16&&(ri.randomFillSync(Ae),je=0),Ae.slice(je,je+=16)}var Ae,je,ot=Z(()=>{Ae=new Uint8Array(256),je=Ae.length});var Dr,Ur=Z(()=>{Dr=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i});function ni(e){return typeof e=="string"&&Dr.test(e)}var ne,$e=Z(()=>{Ur();ne=ni});function le(e,t=0){return R[e[t+0]]+R[e[t+1]]+R[e[t+2]]+R[e[t+3]]+"-"+R[e[t+4]]+R[e[t+5]]+"-"+R[e[t+6]]+R[e[t+7]]+"-"+R[e[t+8]]+R[e[t+9]]+"-"+R[e[t+10]]+R[e[t+11]]+R[e[t+12]]+R[e[t+13]]+R[e[t+14]]+R[e[t+15]]}function ii(e,t=0){let r=le(e,t);if(!ne(r))throw TypeError("Stringified UUID is invalid");return r}var R,Tr,be=Z(()=>{$e();R=[];for(let e=0;e<256;++e)R.push((e+256).toString(16).slice(1));Tr=ii});function ui(e,t,r){let n=t&&r||0,i=t||new Array(16);e=e||{};let u=e.node||qr,s=e.clockseq!==void 0?e.clockseq:at;if(u==null||s==null){let v=e.random||(e.rng||ve)();u==null&&(u=qr=[v[0]|1,v[1],v[2],v[3],v[4],v[5]]),s==null&&(s=at=(v[6]<<8|v[7])&16383)}let f=e.msecs!==void 0?e.msecs:Date.now(),w=e.nsecs!==void 0?e.nsecs:lt+1,g=f-ct+(w-lt)/1e4;if(g<0&&e.clockseq===void 0&&(s=s+1&16383),(g<0||f>ct)&&e.nsecs===void 0&&(w=0),w>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");ct=f,lt=w,at=s,f+=122192928e5;let l=((f&268435455)*1e4+w)%4294967296;i[n++]=l>>>24&255,i[n++]=l>>>16&255,i[n++]=l>>>8&255,i[n++]=l&255;let x=f/4294967296*1e4&268435455;i[n++]=x>>>8&255,i[n++]=x&255,i[n++]=x>>>24&15|16,i[n++]=x>>>16&255,i[n++]=s>>>8|128,i[n++]=s&255;for(let v=0;v<6;++v)i[n+v]=u[v];return t||le(i)}var qr,at,ct,lt,Yr,Cr=Z(()=>{ot();be();ct=0,lt=0;Yr=ui});function si(e){if(!ne(e))throw TypeError("Invalid UUID");let t,r=new Uint8Array(16);return r[0]=(t=parseInt(e.slice(0,8),16))>>>24,r[1]=t>>>16&255,r[2]=t>>>8&255,r[3]=t&255,r[4]=(t=parseInt(e.slice(9,13),16))>>>8,r[5]=t&255,r[6]=(t=parseInt(e.slice(14,18),16))>>>8,r[7]=t&255,r[8]=(t=parseInt(e.slice(19,23),16))>>>8,r[9]=t&255,r[10]=(t=parseInt(e.slice(24,36),16))/1099511627776&255,r[11]=t/4294967296&255,r[12]=t>>>24&255,r[13]=t>>>16&255,r[14]=t>>>8&255,r[15]=t&255,r}var ke,dt=Z(()=>{$e();ke=si});function fi(e){e=unescape(encodeURIComponent(e));let t=[];for(let r=0;r{be();dt();oi="6ba7b810-9dad-11d1-80b4-00c04fd430c8",ai="6ba7b811-9dad-11d1-80b4-00c04fd430c8"});import ci from"crypto";function li(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),ci.createHash("md5").update(e).digest()}var Er,Ir=Z(()=>{Er=li});var di,_r,Wr=Z(()=>{ht();Ir();di=we("v3",48,Er),_r=di});import hi from"crypto";var pt,Fr=Z(()=>{pt={randomUUID:hi.randomUUID}});function pi(e,t,r){if(pt.randomUUID&&!t&&!e)return pt.randomUUID();e=e||{};let n=e.random||(e.rng||ve)();if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,t){r=r||0;for(let i=0;i<16;++i)t[r+i]=n[i];return t}return le(n)}var Hr,Br=Z(()=>{Fr();ot();be();Hr=pi});import mi from"crypto";function gi(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),mi.createHash("sha1").update(e).digest()}var Lr,zr=Z(()=>{Lr=gi});var yi,Pr,Rr=Z(()=>{ht();zr();yi=we("v5",80,Lr),Pr=yi});var Jr,Gr=Z(()=>{Jr="00000000-0000-0000-0000-000000000000"});function vi(e){if(!ne(e))throw TypeError("Invalid UUID");return parseInt(e.slice(14,15),16)}var Zr,Vr=Z(()=>{$e();Zr=vi});var Qr={};on(Qr,{NIL:()=>Jr,parse:()=>ke,stringify:()=>Tr,v1:()=>Yr,v3:()=>_r,v4:()=>Hr,v5:()=>Pr,validate:()=>ne,version:()=>Zr});var Xr=Z(()=>{Cr();Wr();Br();Rr();Gr();Vr();$e();be();dt()});var en=U((Wu,Kr)=>{var $i=(Xr(),cn(Qr)),bi=Kr.exports;bi.uuid=function(){return $i.v4()}});var nn=U((Fu,mt)=>{var{date:wi,duration:Oi}=Mt(),xi={math:Bt(),array:Me(),number:Kt(),url:tr(),string:ir(),comparison:gr(),object:Mr(),regex:kr(),uuid:en()},rn=["sortBy"];mt.exports.helpersToRemoveForJs=rn;var tn={date:wi,duration:Oi},ie;mt.exports.getJsHelperList=()=>{if(ie)return ie;ie={};for(let e of Object.values(xi))for(let[t,r]of Object.entries(e))ie[t]=(...n)=>r(...n,{});for(let e of Object.keys(tn))ie[e]=tn[e];for(let e of rn)delete ie[e];return Object.freeze(ie),ie}});var{getJsHelperList:Si}=nn(),Ni=Si(),Hu={...Ni,stripProtocol:helpersStripProtocol};export{Hu as default}; +const helpers= (() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a, b) => (typeof require !== "undefined" ? require : a)[b] + }) : x)(function(x) { + if (typeof require !== "undefined") + return require.apply(this, arguments); + throw Error('Dynamic require of "' + x + '" is not supported'); + }); + var __esm = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; + }; + var __commonJS = (cb, mod) => function __require2() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + }; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + + // ../../node_modules/dayjs/dayjs.min.js + var require_dayjs_min = __commonJS({ + "../../node_modules/dayjs/dayjs.min.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + }(exports, function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: function t2(e2, n2) { + if (e2.date() < n2.date()) + return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = "$isDayjsObject", S = function(t2) { + return t2 instanceof _ || !(!t2 || !t2[p]); + }, w = function t2(e2, n2, r2) { + var i2; + if (!e2) + return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) + return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, O = function(t2, e2) { + if (S(t2)) + return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, b = v; + b.l = w, b.i = S, b.w = function(t2, e2) { + return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = function() { + function M2(t2) { + this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true; + } + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) + return /* @__PURE__ */ new Date(NaN); + if (b.u(e2)) + return /* @__PURE__ */ new Date(); + if (e2 instanceof Date) + return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + }(t2), this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return b; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = O(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return O(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < O(t2); + }, m2.$g = function(t2, e2, n2) { + return b.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) { + var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, $2 = function(t3, e3) { + return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (f2) { + case h: + return r2 ? l2(1, 0) : l2(31, 11); + case c: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === c || o2 === h) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else + l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[b.p(t2)](); + }, m2.add = function(r2, f2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = b.p(f2), y2 = function(t2) { + var e2 = O(l2); + return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }; + if ($2 === c) + return this.set(c, this.$M + r2); + if ($2 === h) + return this.set(h, this.$y + r2); + if ($2 === a) + return y2(1); + if ($2 === o) + return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return b.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) + return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, d2 = function(t3) { + return b.s(s2 % 12 || 12, t3, "0"); + }, $2 = f2 || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }; + return r2.replace(y, function(t3, r3) { + return r3 || function(t4) { + switch (t4) { + case "YY": + return String(e2.$y).slice(-2); + case "YYYY": + return b.s(e2.$y, 4, "0"); + case "M": + return a2 + 1; + case "MM": + return b.s(a2 + 1, 2, "0"); + case "MMM": + return h2(n2.monthsShort, a2, c2, 3); + case "MMMM": + return h2(c2, a2); + case "D": + return e2.$D; + case "DD": + return b.s(e2.$D, 2, "0"); + case "d": + return String(e2.$W); + case "dd": + return h2(n2.weekdaysMin, e2.$W, o2, 2); + case "ddd": + return h2(n2.weekdaysShort, e2.$W, o2, 3); + case "dddd": + return o2[e2.$W]; + case "H": + return String(s2); + case "HH": + return b.s(s2, 2, "0"); + case "h": + return d2(1); + case "hh": + return d2(2); + case "a": + return $2(s2, u2, true); + case "A": + return $2(s2, u2, false); + case "m": + return String(u2); + case "mm": + return b.s(u2, 2, "0"); + case "s": + return String(e2.$s); + case "ss": + return b.s(e2.$s, 2, "0"); + case "SSS": + return b.s(e2.$ms, 3, "0"); + case "Z": + return i2; + } + return null; + }(t3) || i2.replace(":", ""); + }); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() { + return b.m(y2, m3); + }; + switch (M3) { + case h: + $2 = D2() / 12; + break; + case c: + $2 = D2(); + break; + case f: + $2 = D2() / 3; + break; + case o: + $2 = (g2 - v2) / 6048e5; + break; + case a: + $2 = (g2 - v2) / 864e5; + break; + case u: + $2 = g2 / n; + break; + case s: + $2 = g2 / e; + break; + case i: + $2 = g2 / t; + break; + default: + $2 = g2; + } + return l2 ? $2 : b.a($2); + }, m2.daysInMonth = function() { + return this.endOf(c).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) + return this.$L; + var n2 = this.clone(), r2 = w(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return b.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + }(), k = _.prototype; + return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) { + k[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + }), O.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, O), t2.$i = true), O; + }, O.locale = w, O.isDayjs = S, O.unix = function(t2) { + return O(1e3 * t2); + }, O.en = D[g], O.Ls = D, O.p = {}, O; + }); + } + }); + + // ../../node_modules/dayjs/plugin/duration.js + var require_duration = __commonJS({ + "../../node_modules/dayjs/plugin/duration.js"(exports, module) { + !function(t, s) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = s() : "function" == typeof define && define.amd ? define(s) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_duration = s(); + }(exports, function() { + "use strict"; + var t, s, n = 1e3, i = 6e4, e = 36e5, r = 864e5, o = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, u = 31536e6, d = 2628e6, a = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/, h = { years: u, months: d, days: r, hours: e, minutes: i, seconds: n, milliseconds: 1, weeks: 6048e5 }, c = function(t2) { + return t2 instanceof g; + }, f = function(t2, s2, n2) { + return new g(t2, n2, s2.$l); + }, m = function(t2) { + return s.p(t2) + "s"; + }, l = function(t2) { + return t2 < 0; + }, $ = function(t2) { + return l(t2) ? Math.ceil(t2) : Math.floor(t2); + }, y = function(t2) { + return Math.abs(t2); + }, v = function(t2, s2) { + return t2 ? l(t2) ? { negative: true, format: "" + y(t2) + s2 } : { negative: false, format: "" + t2 + s2 } : { negative: false, format: "" }; + }, g = function() { + function l2(t2, s2, n2) { + var i2 = this; + if (this.$d = {}, this.$l = n2, void 0 === t2 && (this.$ms = 0, this.parseFromMilliseconds()), s2) + return f(t2 * h[m(s2)], this); + if ("number" == typeof t2) + return this.$ms = t2, this.parseFromMilliseconds(), this; + if ("object" == typeof t2) + return Object.keys(t2).forEach(function(s3) { + i2.$d[m(s3)] = t2[s3]; + }), this.calMilliseconds(), this; + if ("string" == typeof t2) { + var e2 = t2.match(a); + if (e2) { + var r2 = e2.slice(2).map(function(t3) { + return null != t3 ? Number(t3) : 0; + }); + return this.$d.years = r2[0], this.$d.months = r2[1], this.$d.weeks = r2[2], this.$d.days = r2[3], this.$d.hours = r2[4], this.$d.minutes = r2[5], this.$d.seconds = r2[6], this.calMilliseconds(), this; + } + } + return this; + } + var y2 = l2.prototype; + return y2.calMilliseconds = function() { + var t2 = this; + this.$ms = Object.keys(this.$d).reduce(function(s2, n2) { + return s2 + (t2.$d[n2] || 0) * h[n2]; + }, 0); + }, y2.parseFromMilliseconds = function() { + var t2 = this.$ms; + this.$d.years = $(t2 / u), t2 %= u, this.$d.months = $(t2 / d), t2 %= d, this.$d.days = $(t2 / r), t2 %= r, this.$d.hours = $(t2 / e), t2 %= e, this.$d.minutes = $(t2 / i), t2 %= i, this.$d.seconds = $(t2 / n), t2 %= n, this.$d.milliseconds = t2; + }, y2.toISOString = function() { + var t2 = v(this.$d.years, "Y"), s2 = v(this.$d.months, "M"), n2 = +this.$d.days || 0; + this.$d.weeks && (n2 += 7 * this.$d.weeks); + var i2 = v(n2, "D"), e2 = v(this.$d.hours, "H"), r2 = v(this.$d.minutes, "M"), o2 = this.$d.seconds || 0; + this.$d.milliseconds && (o2 += this.$d.milliseconds / 1e3, o2 = Math.round(1e3 * o2) / 1e3); + var u2 = v(o2, "S"), d2 = t2.negative || s2.negative || i2.negative || e2.negative || r2.negative || u2.negative, a2 = e2.format || r2.format || u2.format ? "T" : "", h2 = (d2 ? "-" : "") + "P" + t2.format + s2.format + i2.format + a2 + e2.format + r2.format + u2.format; + return "P" === h2 || "-P" === h2 ? "P0D" : h2; + }, y2.toJSON = function() { + return this.toISOString(); + }, y2.format = function(t2) { + var n2 = t2 || "YYYY-MM-DDTHH:mm:ss", i2 = { Y: this.$d.years, YY: s.s(this.$d.years, 2, "0"), YYYY: s.s(this.$d.years, 4, "0"), M: this.$d.months, MM: s.s(this.$d.months, 2, "0"), D: this.$d.days, DD: s.s(this.$d.days, 2, "0"), H: this.$d.hours, HH: s.s(this.$d.hours, 2, "0"), m: this.$d.minutes, mm: s.s(this.$d.minutes, 2, "0"), s: this.$d.seconds, ss: s.s(this.$d.seconds, 2, "0"), SSS: s.s(this.$d.milliseconds, 3, "0") }; + return n2.replace(o, function(t3, s2) { + return s2 || String(i2[t3]); + }); + }, y2.as = function(t2) { + return this.$ms / h[m(t2)]; + }, y2.get = function(t2) { + var s2 = this.$ms, n2 = m(t2); + return "milliseconds" === n2 ? s2 %= 1e3 : s2 = "weeks" === n2 ? $(s2 / h[n2]) : this.$d[n2], s2 || 0; + }, y2.add = function(t2, s2, n2) { + var i2; + return i2 = s2 ? t2 * h[m(s2)] : c(t2) ? t2.$ms : f(t2, this).$ms, f(this.$ms + i2 * (n2 ? -1 : 1), this); + }, y2.subtract = function(t2, s2) { + return this.add(t2, s2, true); + }, y2.locale = function(t2) { + var s2 = this.clone(); + return s2.$l = t2, s2; + }, y2.clone = function() { + return f(this.$ms, this); + }, y2.humanize = function(s2) { + return t().add(this.$ms, "ms").locale(this.$l).fromNow(!s2); + }, y2.valueOf = function() { + return this.asMilliseconds(); + }, y2.milliseconds = function() { + return this.get("milliseconds"); + }, y2.asMilliseconds = function() { + return this.as("milliseconds"); + }, y2.seconds = function() { + return this.get("seconds"); + }, y2.asSeconds = function() { + return this.as("seconds"); + }, y2.minutes = function() { + return this.get("minutes"); + }, y2.asMinutes = function() { + return this.as("minutes"); + }, y2.hours = function() { + return this.get("hours"); + }, y2.asHours = function() { + return this.as("hours"); + }, y2.days = function() { + return this.get("days"); + }, y2.asDays = function() { + return this.as("days"); + }, y2.weeks = function() { + return this.get("weeks"); + }, y2.asWeeks = function() { + return this.as("weeks"); + }, y2.months = function() { + return this.get("months"); + }, y2.asMonths = function() { + return this.as("months"); + }, y2.years = function() { + return this.get("years"); + }, y2.asYears = function() { + return this.as("years"); + }, l2; + }(), p = function(t2, s2, n2) { + return t2.add(s2.years() * n2, "y").add(s2.months() * n2, "M").add(s2.days() * n2, "d").add(s2.hours() * n2, "h").add(s2.minutes() * n2, "m").add(s2.seconds() * n2, "s").add(s2.milliseconds() * n2, "ms"); + }; + return function(n2, i2, e2) { + t = e2, s = e2().$utils(), e2.duration = function(t2, s2) { + var n3 = e2.locale(); + return f(t2, { $l: n3 }, s2); + }, e2.isDuration = c; + var r2 = i2.prototype.add, o2 = i2.prototype.subtract; + i2.prototype.add = function(t2, s2) { + return c(t2) ? p(this, t2, 1) : r2.bind(this)(t2, s2); + }, i2.prototype.subtract = function(t2, s2) { + return c(t2) ? p(this, t2, -1) : o2.bind(this)(t2, s2); + }; + }; + }); + } + }); + + // ../../node_modules/dayjs/plugin/advancedFormat.js + var require_advancedFormat = __commonJS({ + "../../node_modules/dayjs/plugin/advancedFormat.js"(exports, module) { + !function(e, t) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_advancedFormat = t(); + }(exports, function() { + "use strict"; + return function(e, t) { + var r = t.prototype, n = r.format; + r.format = function(e2) { + var t2 = this, r2 = this.$locale(); + if (!this.isValid()) + return n.bind(this)(e2); + var s = this.$utils(), a = (e2 || "YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g, function(e3) { + switch (e3) { + case "Q": + return Math.ceil((t2.$M + 1) / 3); + case "Do": + return r2.ordinal(t2.$D); + case "gggg": + return t2.weekYear(); + case "GGGG": + return t2.isoWeekYear(); + case "wo": + return r2.ordinal(t2.week(), "W"); + case "w": + case "ww": + return s.s(t2.week(), "w" === e3 ? 1 : 2, "0"); + case "W": + case "WW": + return s.s(t2.isoWeek(), "W" === e3 ? 1 : 2, "0"); + case "k": + case "kk": + return s.s(String(0 === t2.$H ? 24 : t2.$H), "k" === e3 ? 1 : 2, "0"); + case "X": + return Math.floor(t2.$d.getTime() / 1e3); + case "x": + return t2.$d.getTime(); + case "z": + return "[" + t2.offsetName() + "]"; + case "zzz": + return "[" + t2.offsetName("long") + "]"; + default: + return e3; + } + }); + return n.bind(this)(a); + }; + }; + }); + } + }); + + // ../../node_modules/dayjs/plugin/isoWeek.js + var require_isoWeek = __commonJS({ + "../../node_modules/dayjs/plugin/isoWeek.js"(exports, module) { + !function(e, t) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_isoWeek = t(); + }(exports, function() { + "use strict"; + var e = "day"; + return function(t, i, s) { + var a = function(t2) { + return t2.add(4 - t2.isoWeekday(), e); + }, d = i.prototype; + d.isoWeekYear = function() { + return a(this).year(); + }, d.isoWeek = function(t2) { + if (!this.$utils().u(t2)) + return this.add(7 * (t2 - this.isoWeek()), e); + var i2, d2, n2, o, r = a(this), u = (i2 = this.isoWeekYear(), d2 = this.$u, n2 = (d2 ? s.utc : s)().year(i2).startOf("year"), o = 4 - n2.isoWeekday(), n2.isoWeekday() > 4 && (o += 7), n2.add(o, e)); + return r.diff(u, "week") + 1; + }, d.isoWeekday = function(e2) { + return this.$utils().u(e2) ? this.day() || 7 : this.day(this.day() % 7 ? e2 : e2 - 7); + }; + var n = d.startOf; + d.startOf = function(e2, t2) { + var i2 = this.$utils(), s2 = !!i2.u(t2) || t2; + return "isoweek" === i2.p(e2) ? s2 ? this.date(this.date() - (this.isoWeekday() - 1)).startOf("day") : this.date(this.date() - 1 - (this.isoWeekday() - 1) + 7).endOf("day") : n.bind(this)(e2, t2); + }; + }; + }); + } + }); + + // ../../node_modules/dayjs/plugin/weekYear.js + var require_weekYear = __commonJS({ + "../../node_modules/dayjs/plugin/weekYear.js"(exports, module) { + !function(e, t) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_weekYear = t(); + }(exports, function() { + "use strict"; + return function(e, t) { + t.prototype.weekYear = function() { + var e2 = this.month(), t2 = this.week(), n = this.year(); + return 1 === t2 && 11 === e2 ? n + 1 : 0 === e2 && t2 >= 52 ? n - 1 : n; + }; + }; + }); + } + }); + + // ../../node_modules/dayjs/plugin/weekOfYear.js + var require_weekOfYear = __commonJS({ + "../../node_modules/dayjs/plugin/weekOfYear.js"(exports, module) { + !function(e, t) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_weekOfYear = t(); + }(exports, function() { + "use strict"; + var e = "week", t = "year"; + return function(i, n, r) { + var f = n.prototype; + f.week = function(i2) { + if (void 0 === i2 && (i2 = null), null !== i2) + return this.add(7 * (i2 - this.week()), "day"); + var n2 = this.$locale().yearStart || 1; + if (11 === this.month() && this.date() > 25) { + var f2 = r(this).startOf(t).add(1, t).date(n2), s = r(this).endOf(e); + if (f2.isBefore(s)) + return 1; + } + var a = r(this).startOf(t).date(n2).startOf(e).subtract(1, "millisecond"), o = this.diff(a, e, true); + return o < 0 ? r(this).startOf("week").week() : Math.ceil(o); + }, f.weeks = function(e2) { + return void 0 === e2 && (e2 = null), this.week(e2); + }; + }; + }); + } + }); + + // ../../node_modules/dayjs/plugin/relativeTime.js + var require_relativeTime = __commonJS({ + "../../node_modules/dayjs/plugin/relativeTime.js"(exports, module) { + !function(r, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (r = "undefined" != typeof globalThis ? globalThis : r || self).dayjs_plugin_relativeTime = e(); + }(exports, function() { + "use strict"; + return function(r, e, t) { + r = r || {}; + var n = e.prototype, o = { future: "in %s", past: "%s ago", s: "a few seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", M: "a month", MM: "%d months", y: "a year", yy: "%d years" }; + function i(r2, e2, t2, o2) { + return n.fromToBase(r2, e2, t2, o2); + } + t.en.relativeTime = o, n.fromToBase = function(e2, n2, i2, d2, u) { + for (var f, a, s, l = i2.$locale().relativeTime || o, h = r.thresholds || [{ l: "s", r: 44, d: "second" }, { l: "m", r: 89 }, { l: "mm", r: 44, d: "minute" }, { l: "h", r: 89 }, { l: "hh", r: 21, d: "hour" }, { l: "d", r: 35 }, { l: "dd", r: 25, d: "day" }, { l: "M", r: 45 }, { l: "MM", r: 10, d: "month" }, { l: "y", r: 17 }, { l: "yy", d: "year" }], m = h.length, c = 0; c < m; c += 1) { + var y = h[c]; + y.d && (f = d2 ? t(e2).diff(i2, y.d, true) : i2.diff(e2, y.d, true)); + var p = (r.rounding || Math.round)(Math.abs(f)); + if (s = f > 0, p <= y.r || !y.r) { + p <= 1 && c > 0 && (y = h[c - 1]); + var v = l[y.l]; + u && (p = u("" + p)), a = "string" == typeof v ? v.replace("%d", p) : v(p, n2, y.l, s); + break; + } + } + if (n2) + return a; + var M = s ? l.future : l.past; + return "function" == typeof M ? M(a) : M.replace("%s", a); + }, n.to = function(r2, e2) { + return i(r2, e2, this, true); + }, n.from = function(r2, e2) { + return i(r2, e2, this); + }; + var d = function(r2) { + return r2.$u ? t.utc() : t(); + }; + n.toNow = function(r2) { + return this.to(d(this), r2); + }, n.fromNow = function(r2) { + return this.from(d(this), r2); + }; + }; + }); + } + }); + + // ../../node_modules/dayjs/plugin/utc.js + var require_utc = __commonJS({ + "../../node_modules/dayjs/plugin/utc.js"(exports, module) { + !function(t, i) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_utc = i(); + }(exports, function() { + "use strict"; + var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g; + return function(s, f, n) { + var u = f.prototype; + n.utc = function(t2) { + var i2 = { date: t2, utc: true, args: arguments }; + return new f(i2); + }, u.utc = function(i2) { + var e2 = n(this.toDate(), { locale: this.$L, utc: true }); + return i2 ? e2.add(this.utcOffset(), t) : e2; + }, u.local = function() { + return n(this.toDate(), { locale: this.$L, utc: false }); + }; + var o = u.parse; + u.parse = function(t2) { + t2.utc && (this.$u = true), this.$utils().u(t2.$offset) || (this.$offset = t2.$offset), o.call(this, t2); + }; + var r = u.init; + u.init = function() { + if (this.$u) { + var t2 = this.$d; + this.$y = t2.getUTCFullYear(), this.$M = t2.getUTCMonth(), this.$D = t2.getUTCDate(), this.$W = t2.getUTCDay(), this.$H = t2.getUTCHours(), this.$m = t2.getUTCMinutes(), this.$s = t2.getUTCSeconds(), this.$ms = t2.getUTCMilliseconds(); + } else + r.call(this); + }; + var a = u.utcOffset; + u.utcOffset = function(s2, f2) { + var n2 = this.$utils().u; + if (n2(s2)) + return this.$u ? 0 : n2(this.$offset) ? a.call(this) : this.$offset; + if ("string" == typeof s2 && (s2 = function(t2) { + void 0 === t2 && (t2 = ""); + var s3 = t2.match(i); + if (!s3) + return null; + var f3 = ("" + s3[0]).match(e) || ["-", 0, 0], n3 = f3[0], u3 = 60 * +f3[1] + +f3[2]; + return 0 === u3 ? 0 : "+" === n3 ? u3 : -u3; + }(s2), null === s2)) + return this; + var u2 = Math.abs(s2) <= 16 ? 60 * s2 : s2, o2 = this; + if (f2) + return o2.$offset = u2, o2.$u = 0 === s2, o2; + if (0 !== s2) { + var r2 = this.$u ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset(); + (o2 = this.local().add(u2 + r2, t)).$offset = u2, o2.$x.$localOffset = r2; + } else + o2 = this.utc(); + return o2; + }; + var h = u.format; + u.format = function(t2) { + var i2 = t2 || (this.$u ? "YYYY-MM-DDTHH:mm:ss[Z]" : ""); + return h.call(this, i2); + }, u.valueOf = function() { + var t2 = this.$utils().u(this.$offset) ? 0 : this.$offset + (this.$x.$localOffset || this.$d.getTimezoneOffset()); + return this.$d.valueOf() - 6e4 * t2; + }, u.isUTC = function() { + return !!this.$u; + }, u.toISOString = function() { + return this.toDate().toISOString(); + }, u.toString = function() { + return this.toDate().toUTCString(); + }; + var l = u.toDate; + u.toDate = function(t2) { + return "s" === t2 && this.$offset ? n(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate() : l.call(this); + }; + var c = u.diff; + u.diff = function(t2, i2, e2) { + if (t2 && this.$u === t2.$u) + return c.call(this, t2, i2, e2); + var s2 = this.local(), f2 = n(t2).local(); + return c.call(s2, f2, i2, e2); + }; + }; + }); + } + }); + + // ../../node_modules/dayjs/plugin/timezone.js + var require_timezone = __commonJS({ + "../../node_modules/dayjs/plugin/timezone.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_timezone = e(); + }(exports, function() { + "use strict"; + var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {}; + return function(n, i, o) { + var r, a = function(t2, n2, i2) { + void 0 === i2 && (i2 = {}); + var o2 = new Date(t2), r2 = function(t3, n3) { + void 0 === n3 && (n3 = {}); + var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3]; + return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3; + }(n2, i2); + return r2.formatToParts(o2); + }, u = function(e2, n2) { + for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) { + var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2]; + c >= 0 && (r2[c] = parseInt(m, 10)); + } + var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2; + return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4; + }, f = i.prototype; + f.tz = function(t2, e2) { + void 0 === t2 && (t2 = r); + var n2 = this.utcOffset(), i2 = this.toDate(), a2 = i2.toLocaleString("en-US", { timeZone: t2 }), u2 = Math.round((i2 - new Date(a2)) / 1e3 / 60), f2 = o(a2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(15 * -Math.round(i2.getTimezoneOffset() / 15) - u2, true); + if (e2) { + var s2 = f2.utcOffset(); + f2 = f2.add(n2 - s2, "minute"); + } + return f2.$x.$timezone = t2, f2; + }, f.offsetName = function(t2) { + var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find(function(t3) { + return "timezonename" === t3.type.toLowerCase(); + }); + return n2 && n2.value; + }; + var s = f.startOf; + f.startOf = function(t2, e2) { + if (!this.$x || !this.$x.$timezone) + return s.call(this, t2, e2); + var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L }); + return s.call(n2, t2, e2).tz(this.$x.$timezone, true); + }, o.tz = function(t2, e2, n2) { + var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2); + if ("string" != typeof t2) + return o(t2).tz(a2); + var s2 = function(t3, e3, n3) { + var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3); + if (e3 === o2) + return [i3, e3]; + var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3); + return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)]; + }(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c); + return d.$x.$timezone = a2, d; + }, o.tz.guess = function() { + return Intl.DateTimeFormat().resolvedOptions().timeZone; + }, o.tz.setDefault = function(t2) { + r = t2; + }; + }; + }); + } + }); + + // ../string-templates/src/helpers/date.js + var require_date = __commonJS({ + "../string-templates/src/helpers/date.js"(exports, module) { + var dayjs = require_dayjs_min(); + dayjs.extend(require_duration()); + dayjs.extend(require_advancedFormat()); + dayjs.extend(require_isoWeek()); + dayjs.extend(require_weekYear()); + dayjs.extend(require_weekOfYear()); + dayjs.extend(require_relativeTime()); + dayjs.extend(require_utc()); + dayjs.extend(require_timezone()); + function isOptions(val) { + return typeof val === "object" && typeof val.hash === "object"; + } + function isApp(thisArg) { + return typeof thisArg === "object" && typeof thisArg.options === "object" && typeof thisArg.app === "object"; + } + function getContext(thisArg, locals, options) { + if (isOptions(thisArg)) { + return getContext({}, locals, thisArg); + } + if (isOptions(locals)) { + return getContext(thisArg, options, locals); + } + const appContext = isApp(thisArg) ? thisArg.context : {}; + options = options || {}; + if (!isOptions(options)) { + locals = Object.assign({}, locals, options); + } + if (isOptions(options) && options.hash.root === true) { + locals = Object.assign({}, options.data.root, locals); + } + let context = Object.assign({}, appContext, locals, options.hash); + if (!isApp(thisArg)) { + context = Object.assign({}, thisArg, context); + } + if (isApp(thisArg) && thisArg.view && thisArg.view.data) { + context = Object.assign({}, context, thisArg.view.data); + } + return context; + } + function initialConfig(str, pattern, options) { + if (isOptions(pattern)) { + options = pattern; + pattern = null; + } + if (isOptions(str)) { + options = str; + pattern = null; + str = null; + } + return { str, pattern, options }; + } + function setLocale(str, pattern, options) { + const config = initialConfig(str, pattern, options); + const defaults = { lang: "en", date: new Date(config.str) }; + const opts = getContext(this, defaults, {}); + dayjs.locale(opts.lang || opts.language); + } + module.exports.date = (str, pattern, options) => { + const config = initialConfig(str, pattern, options); + if (config.str == null && config.pattern == null) { + dayjs.locale("en"); + return dayjs().format("MMMM DD, YYYY"); + } + setLocale(config.str, config.pattern, config.options); + let date = dayjs(new Date(config.str)); + if (typeof config.options === "string") { + date = config.options.toLowerCase() === "utc" ? date.utc() : date.tz(config.options); + } else { + date = date.tz(dayjs.tz.guess()); + } + if (config.pattern === "") { + return date.toISOString(); + } + return date.format(config.pattern); + }; + module.exports.duration = (str, pattern, format) => { + const config = initialConfig(str, pattern); + setLocale(config.str, config.pattern); + const duration = dayjs.duration(config.str, config.pattern); + if (format && !isOptions(format)) { + return duration.format(format); + } else { + return duration.humanize(); + } + }; + } + }); + + // ../../node_modules/is-buffer/index.js + var require_is_buffer = __commonJS({ + "../../node_modules/is-buffer/index.js"(exports, module) { + module.exports = function(obj) { + return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer); + }; + function isBuffer(obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === "function" && obj.constructor.isBuffer(obj); + } + function isSlowBuffer(obj) { + return typeof obj.readFloatLE === "function" && typeof obj.slice === "function" && isBuffer(obj.slice(0, 0)); + } + } + }); + + // ../../node_modules/typeof-article/node_modules/kind-of/index.js + var require_kind_of = __commonJS({ + "../../node_modules/typeof-article/node_modules/kind-of/index.js"(exports, module) { + var isBuffer = require_is_buffer(); + var toString = Object.prototype.toString; + module.exports = function kindOf(val) { + if (typeof val === "undefined") { + return "undefined"; + } + if (val === null) { + return "null"; + } + if (val === true || val === false || val instanceof Boolean) { + return "boolean"; + } + if (typeof val === "string" || val instanceof String) { + return "string"; + } + if (typeof val === "number" || val instanceof Number) { + return "number"; + } + if (typeof val === "function" || val instanceof Function) { + return "function"; + } + if (typeof Array.isArray !== "undefined" && Array.isArray(val)) { + return "array"; + } + if (val instanceof RegExp) { + return "regexp"; + } + if (val instanceof Date) { + return "date"; + } + var type = toString.call(val); + if (type === "[object RegExp]") { + return "regexp"; + } + if (type === "[object Date]") { + return "date"; + } + if (type === "[object Arguments]") { + return "arguments"; + } + if (type === "[object Error]") { + return "error"; + } + if (isBuffer(val)) { + return "buffer"; + } + if (type === "[object Set]") { + return "set"; + } + if (type === "[object WeakSet]") { + return "weakset"; + } + if (type === "[object Map]") { + return "map"; + } + if (type === "[object WeakMap]") { + return "weakmap"; + } + if (type === "[object Symbol]") { + return "symbol"; + } + if (type === "[object Int8Array]") { + return "int8array"; + } + if (type === "[object Uint8Array]") { + return "uint8array"; + } + if (type === "[object Uint8ClampedArray]") { + return "uint8clampedarray"; + } + if (type === "[object Int16Array]") { + return "int16array"; + } + if (type === "[object Uint16Array]") { + return "uint16array"; + } + if (type === "[object Int32Array]") { + return "int32array"; + } + if (type === "[object Uint32Array]") { + return "uint32array"; + } + if (type === "[object Float32Array]") { + return "float32array"; + } + if (type === "[object Float64Array]") { + return "float64array"; + } + return "object"; + }; + } + }); + + // ../../node_modules/typeof-article/index.js + var require_typeof_article = __commonJS({ + "../../node_modules/typeof-article/index.js"(exports, module) { + "use strict"; + var typeOf = require_kind_of(); + var types = { + "arguments": "an arguments object", + "array": "an array", + "boolean": "a boolean", + "buffer": "a buffer", + "date": "a date", + "error": "an error", + "float32array": "a float32array", + "float64array": "a float64array", + "function": "a function", + "int16array": "an int16array", + "int32array": "an int32array", + "int8array": "an int8array", + "map": "a Map", + "null": "null", + "number": "a number", + "object": "an object", + "regexp": "a regular expression", + "set": "a Set", + "string": "a string", + "symbol": "a symbol", + "uint16array": "an uint16array", + "uint32array": "an uint32array", + "uint8array": "an uint8array", + "uint8clampedarray": "an uint8clampedarray", + "undefined": "undefined", + "weakmap": "a WeakMap", + "weakset": "a WeakSet" + }; + function type(val) { + return types[typeOf(val)]; + } + type.types = types; + type.typeOf = typeOf; + module.exports = type; + } + }); + + // ../../node_modules/kind-of/index.js + var require_kind_of2 = __commonJS({ + "../../node_modules/kind-of/index.js"(exports, module) { + var toString = Object.prototype.toString; + module.exports = function kindOf(val) { + if (val === void 0) + return "undefined"; + if (val === null) + return "null"; + var type = typeof val; + if (type === "boolean") + return "boolean"; + if (type === "string") + return "string"; + if (type === "number") + return "number"; + if (type === "symbol") + return "symbol"; + if (type === "function") { + return isGeneratorFn(val) ? "generatorfunction" : "function"; + } + if (isArray(val)) + return "array"; + if (isBuffer(val)) + return "buffer"; + if (isArguments(val)) + return "arguments"; + if (isDate(val)) + return "date"; + if (isError(val)) + return "error"; + if (isRegexp(val)) + return "regexp"; + switch (ctorName(val)) { + case "Symbol": + return "symbol"; + case "Promise": + return "promise"; + case "WeakMap": + return "weakmap"; + case "WeakSet": + return "weakset"; + case "Map": + return "map"; + case "Set": + return "set"; + case "Int8Array": + return "int8array"; + case "Uint8Array": + return "uint8array"; + case "Uint8ClampedArray": + return "uint8clampedarray"; + case "Int16Array": + return "int16array"; + case "Uint16Array": + return "uint16array"; + case "Int32Array": + return "int32array"; + case "Uint32Array": + return "uint32array"; + case "Float32Array": + return "float32array"; + case "Float64Array": + return "float64array"; + } + if (isGeneratorObj(val)) { + return "generator"; + } + type = toString.call(val); + switch (type) { + case "[object Object]": + return "object"; + case "[object Map Iterator]": + return "mapiterator"; + case "[object Set Iterator]": + return "setiterator"; + case "[object String Iterator]": + return "stringiterator"; + case "[object Array Iterator]": + return "arrayiterator"; + } + return type.slice(8, -1).toLowerCase().replace(/\s/g, ""); + }; + function ctorName(val) { + return typeof val.constructor === "function" ? val.constructor.name : null; + } + function isArray(val) { + if (Array.isArray) + return Array.isArray(val); + return val instanceof Array; + } + function isError(val) { + return val instanceof Error || typeof val.message === "string" && val.constructor && typeof val.constructor.stackTraceLimit === "number"; + } + function isDate(val) { + if (val instanceof Date) + return true; + return typeof val.toDateString === "function" && typeof val.getDate === "function" && typeof val.setDate === "function"; + } + function isRegexp(val) { + if (val instanceof RegExp) + return true; + return typeof val.flags === "string" && typeof val.ignoreCase === "boolean" && typeof val.multiline === "boolean" && typeof val.global === "boolean"; + } + function isGeneratorFn(name, val) { + return ctorName(name) === "GeneratorFunction"; + } + function isGeneratorObj(val) { + return typeof val.throw === "function" && typeof val.return === "function" && typeof val.next === "function"; + } + function isArguments(val) { + try { + if (typeof val.length === "number" && typeof val.callee === "function") { + return true; + } + } catch (err) { + if (err.message.indexOf("callee") !== -1) { + return true; + } + } + return false; + } + function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === "function") { + return val.constructor.isBuffer(val); + } + return false; + } + } + }); + + // ../../node_modules/handlebars-utils/index.js + var require_handlebars_utils = __commonJS({ + "../../node_modules/handlebars-utils/index.js"(exports, module) { + "use strict"; + var util = __require("util"); + var type = require_typeof_article(); + var typeOf = require_kind_of2(); + var utils = exports = module.exports; + utils.extend = extend; + utils.indexOf = indexOf; + utils.escapeExpression = escapeExpression; + utils.isEmpty = isEmpty; + utils.createFrame = createFrame; + utils.blockParams = blockParams; + utils.appendContextPath = appendContextPath; + var escape = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`", + "=": "=" + }; + var badChars = /[&<>"'`=]/g; + var possible = /[&<>"'`=]/; + function escapeChar(chr) { + return escape[chr]; + } + function extend(obj) { + for (var i = 1; i < arguments.length; i++) { + for (var key in arguments[i]) { + if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { + obj[key] = arguments[i][key]; + } + } + } + return obj; + } + var toString = Object.prototype.toString; + utils.toString = toString; + var isFunction = function isFunction2(value2) { + return typeof value2 === "function"; + }; + if (isFunction(/x/)) { + utils.isFunction = isFunction = function(value2) { + return typeof value2 === "function" && toString.call(value2) === "[object Function]"; + }; + } + utils.isFunction = isFunction; + var isArray = Array.isArray || function(value2) { + return value2 && typeof value2 === "object" ? toString.call(value2) === "[object Array]" : false; + }; + utils.isArray = isArray; + function indexOf(array, value2) { + for (var i = 0, len = array.length; i < len; i++) { + if (array[i] === value2) { + return i; + } + } + return -1; + } + function escapeExpression(string) { + if (typeof string !== "string") { + if (string && string.toHTML) { + return string.toHTML(); + } else if (string == null) { + return ""; + } else if (!string) { + return string + ""; + } + string = "" + string; + } + if (!possible.test(string)) { + return string; + } + return string.replace(badChars, escapeChar); + } + function createFrame(object) { + var frame = extend({}, object); + frame._parent = object; + return frame; + } + function blockParams(params, ids) { + params.path = ids; + return params; + } + function appendContextPath(contextPath, id) { + return (contextPath ? contextPath + "." : "") + id; + } + utils.expectedType = function(param, expected, actual) { + var exp = type.types[expected]; + var val = util.inspect(actual); + return "expected " + param + " to be " + exp + " but received " + type(actual) + ": " + val; + }; + utils.isBlock = function(options) { + return utils.isOptions(options) && typeof options.fn === "function" && typeof options.inverse === "function"; + }; + utils.fn = function(val, context, options) { + if (utils.isOptions(val)) { + return utils.fn("", val, options); + } + if (utils.isOptions(context)) { + return utils.fn(val, {}, context); + } + return utils.isBlock(options) ? options.fn(context) : val; + }; + utils.inverse = function(val, context, options) { + if (utils.isOptions(val)) { + return utils.identity("", val, options); + } + if (utils.isOptions(context)) { + return utils.inverse(val, {}, context); + } + return utils.isBlock(options) ? options.inverse(context) : val; + }; + utils.value = function(val, context, options) { + if (utils.isOptions(val)) { + return utils.value(null, val, options); + } + if (utils.isOptions(context)) { + return utils.value(val, {}, context); + } + if (utils.isBlock(options)) { + return !!val ? options.fn(context) : options.inverse(context); + } + return val; + }; + utils.isOptions = function(val) { + return utils.isObject(val) && utils.isObject(val.hash); + }; + utils.isUndefined = function(val) { + return val == null || utils.isOptions(val) && val.hash != null; + }; + utils.isApp = function(thisArg) { + return utils.isObject(thisArg) && utils.isObject(thisArg.options) && utils.isObject(thisArg.app); + }; + utils.options = function(thisArg, locals, options) { + if (utils.isOptions(thisArg)) { + return utils.options({}, locals, thisArg); + } + if (utils.isOptions(locals)) { + return utils.options(thisArg, options, locals); + } + options = options || {}; + if (!utils.isOptions(options)) { + locals = Object.assign({}, locals, options); + } + var opts = Object.assign({}, locals, options.hash); + if (utils.isObject(thisArg)) { + opts = Object.assign({}, thisArg.options, opts); + } + if (opts[options.name]) { + opts = Object.assign({}, opts[options.name], opts); + } + return opts; + }; + utils.context = function(thisArg, locals, options) { + if (utils.isOptions(thisArg)) { + return utils.context({}, locals, thisArg); + } + if (utils.isOptions(locals)) { + return utils.context(thisArg, options, locals); + } + var appContext = utils.isApp(thisArg) ? thisArg.context : {}; + options = options || {}; + if (!utils.isOptions(options)) { + locals = Object.assign({}, locals, options); + } + if (utils.isOptions(options) && options.hash.root === true) { + locals = Object.assign({}, options.data.root, locals); + } + var context = Object.assign({}, appContext, locals, options.hash); + if (!utils.isApp(thisArg)) { + context = Object.assign({}, thisArg, context); + } + if (utils.isApp(thisArg) && thisArg.view && thisArg.view.data) { + context = Object.assign({}, context, thisArg.view.data); + } + return context; + }; + utils.isObject = function(val) { + return typeOf(val) === "object"; + }; + function isEmpty(val) { + if (val === 0 || typeof val === "boolean") { + return false; + } + if (val == null) { + return true; + } + if (utils.isObject(val)) { + val = Object.keys(val); + } + if (!val.length) { + return true; + } + return false; + } + utils.result = function(val) { + if (typeof val === "function") { + return val.apply(this, [].slice.call(arguments, 1)); + } + return val; + }; + utils.identity = function(val) { + return val; + }; + utils.isString = function(val) { + return typeof val === "string" && val !== ""; + }; + utils.arrayify = function(val) { + return val != null ? Array.isArray(val) ? val : [val] : []; + }; + utils.tryParse = function(str) { + try { + return JSON.parse(str); + } catch (err) { + } + return {}; + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/utils/index.js + var require_utils = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/utils/index.js"(exports) { + "use strict"; + var util = require_handlebars_utils(); + exports.contains = function(val, obj, start) { + if (val == null || obj == null || isNaN(val.length)) { + return false; + } + return val.indexOf(obj, start) !== -1; + }; + exports.chop = function(str) { + if (typeof str !== "string") + return ""; + var re = /^[-_.\W\s]+|[-_.\W\s]+$/g; + return str.trim().replace(re, ""); + }; + exports.changecase = function(str, fn) { + if (typeof str !== "string") + return ""; + if (str.length === 1) { + return str.toLowerCase(); + } + str = exports.chop(str).toLowerCase(); + if (typeof fn !== "function") { + fn = util.identity; + } + var re = /[-_.\W\s]+(\w|$)/g; + return str.replace(re, function(_, ch) { + return fn(ch); + }); + }; + exports.random = function(min, max) { + return min + Math.floor(Math.random() * (max - min + 1)); + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/math.js + var require_math = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/math.js"(exports, module) { + "use strict"; + var utils = require_utils(); + var helpers2 = module.exports; + helpers2.abs = function(num) { + if (isNaN(num)) { + throw new TypeError("expected a number"); + } + return Math.abs(num); + }; + helpers2.add = function(a, b) { + if (!isNaN(a) && !isNaN(b)) { + return Number(a) + Number(b); + } + if (typeof a === "string" && typeof b === "string") { + return a + b; + } + return ""; + }; + helpers2.avg = function() { + const args = [].concat.apply([], arguments); + args.pop(); + return helpers2.sum(args) / args.length; + }; + helpers2.ceil = function(num) { + if (isNaN(num)) { + throw new TypeError("expected a number"); + } + return Math.ceil(num); + }; + helpers2.divide = function(a, b) { + if (isNaN(a)) { + throw new TypeError("expected the first argument to be a number"); + } + if (isNaN(b)) { + throw new TypeError("expected the second argument to be a number"); + } + return Number(a) / Number(b); + }; + helpers2.floor = function(num) { + if (isNaN(num)) { + throw new TypeError("expected a number"); + } + return Math.floor(num); + }; + helpers2.minus = function(a, b) { + if (isNaN(a)) { + throw new TypeError("expected the first argument to be a number"); + } + if (isNaN(b)) { + throw new TypeError("expected the second argument to be a number"); + } + return Number(a) - Number(b); + }; + helpers2.modulo = function(a, b) { + if (isNaN(a)) { + throw new TypeError("expected the first argument to be a number"); + } + if (isNaN(b)) { + throw new TypeError("expected the second argument to be a number"); + } + return Number(a) % Number(b); + }; + helpers2.multiply = function(a, b) { + if (isNaN(a)) { + throw new TypeError("expected the first argument to be a number"); + } + if (isNaN(b)) { + throw new TypeError("expected the second argument to be a number"); + } + return Number(a) * Number(b); + }; + helpers2.plus = function(a, b) { + if (isNaN(a)) { + throw new TypeError("expected the first argument to be a number"); + } + if (isNaN(b)) { + throw new TypeError("expected the second argument to be a number"); + } + return Number(a) + Number(b); + }; + helpers2.random = function(min, max) { + if (isNaN(min)) { + throw new TypeError("expected minimum to be a number"); + } + if (isNaN(max)) { + throw new TypeError("expected maximum to be a number"); + } + return utils.random(min, max); + }; + helpers2.remainder = function(a, b) { + return a % b; + }; + helpers2.round = function(num) { + if (isNaN(num)) { + throw new TypeError("expected a number"); + } + return Math.round(num); + }; + helpers2.subtract = function(a, b) { + if (isNaN(a)) { + throw new TypeError("expected the first argument to be a number"); + } + if (isNaN(b)) { + throw new TypeError("expected the second argument to be a number"); + } + return Number(a) - Number(b); + }; + helpers2.sum = function() { + var args = [].concat.apply([], arguments); + var len = args.length; + var sum = 0; + while (len--) { + if (!isNaN(args[len])) { + sum += Number(args[len]); + } + } + return sum; + }; + } + }); + + // ../../node_modules/isobject/index.js + var require_isobject = __commonJS({ + "../../node_modules/isobject/index.js"(exports, module) { + "use strict"; + module.exports = function isObject(val) { + return val != null && typeof val === "object" && Array.isArray(val) === false; + }; + } + }); + + // ../../node_modules/get-value/index.js + var require_get_value = __commonJS({ + "../../node_modules/get-value/index.js"(exports, module) { + var isObject = require_isobject(); + module.exports = function(target, path, options) { + if (!isObject(options)) { + options = { default: options }; + } + if (!isValidObject(target)) { + return typeof options.default !== "undefined" ? options.default : target; + } + if (typeof path === "number") { + path = String(path); + } + const isArray = Array.isArray(path); + const isString = typeof path === "string"; + const splitChar = options.separator || "."; + const joinChar = options.joinChar || (typeof splitChar === "string" ? splitChar : "."); + if (!isString && !isArray) { + return target; + } + if (isString && path in target) { + return isValid(path, target, options) ? target[path] : options.default; + } + let segs = isArray ? path : split(path, splitChar, options); + let len = segs.length; + let idx = 0; + do { + let prop = segs[idx]; + if (typeof prop === "number") { + prop = String(prop); + } + while (prop && prop.slice(-1) === "\\") { + prop = join([prop.slice(0, -1), segs[++idx] || ""], joinChar, options); + } + if (prop in target) { + if (!isValid(prop, target, options)) { + return options.default; + } + target = target[prop]; + } else { + let hasProp = false; + let n = idx + 1; + while (n < len) { + prop = join([prop, segs[n++]], joinChar, options); + if (hasProp = prop in target) { + if (!isValid(prop, target, options)) { + return options.default; + } + target = target[prop]; + idx = n - 1; + break; + } + } + if (!hasProp) { + return options.default; + } + } + } while (++idx < len && isValidObject(target)); + if (idx === len) { + return target; + } + return options.default; + }; + function join(segs, joinChar, options) { + if (typeof options.join === "function") { + return options.join(segs); + } + return segs[0] + joinChar + segs[1]; + } + function split(path, splitChar, options) { + if (typeof options.split === "function") { + return options.split(path); + } + return path.split(splitChar); + } + function isValid(key, target, options) { + if (typeof options.isValid === "function") { + return options.isValid(key, target); + } + return true; + } + function isValidObject(val) { + return isObject(val) || Array.isArray(val) || typeof val === "function"; + } + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/utils/createFrame.js + var require_createFrame = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/utils/createFrame.js"(exports, module) { + "use strict"; + module.exports = function createFrame(data) { + if (typeof data !== "object") { + throw new TypeError("createFrame expects data to be an object"); + } + var frame = Object.assign({}, data); + frame._parent = data; + frame.extend = function(data2) { + Object.assign(this, data2); + }; + if (arguments.length > 1) { + var args = [].slice.call(arguments, 1); + var len = args.length, i = -1; + while (++i < len) { + frame.extend(args[i] || {}); + } + } + return frame; + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/array.js + var require_array = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/array.js"(exports, module) { + "use strict"; + var util = require_handlebars_utils(); + var helpers2 = module.exports; + var getValue = require_get_value(); + var createFrame = require_createFrame(); + helpers2.after = function(array, n) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + return array.slice(n); + } + return ""; + }; + helpers2.arrayify = function(value2) { + if (util.isUndefined(value2)) + return []; + return value2 ? Array.isArray(value2) ? value2 : [value2] : []; + }; + helpers2.before = function(array, n) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + return array.slice(0, n - 1); + } + return ""; + }; + helpers2.eachIndex = function(array, options) { + var result = ""; + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + for (var i = 0; i < array.length; i++) { + result += options.fn({ item: array[i], index: i }); + } + } + return result; + }; + helpers2.filter = function(array, value2, options) { + if (util.isUndefined(array)) + return options.inverse(this); + array = util.result(array); + if (Array.isArray(array)) { + var content = ""; + var results = []; + var prop = options.hash && (options.hash.property || options.hash.prop); + if (prop) { + results = array.filter(function(val) { + return value2 === getValue(val, prop); + }); + } else { + results = array.filter(function(v) { + return value2 === v; + }); + } + if (results && results.length > 0) { + for (var i = 0; i < results.length; i++) { + content += options.fn(results[i]); + } + return content; + } + } + return options.inverse(this); + }; + helpers2.first = function(array, n) { + if (util.isUndefined(array)) + return []; + array = util.result(array); + if (Array.isArray(array)) { + if (isNaN(n)) { + return array[0]; + } + return array.slice(0, n); + } + return []; + }; + helpers2.forEach = function(array, options) { + if (util.isUndefined(array)) + return options.inverse(this); + array = util.result(array); + if (Array.isArray(array)) { + var data = createFrame(options, options.hash); + var len = array.length; + var buffer = ""; + var i = -1; + while (++i < len) { + var item = array[i]; + data.index = i; + item.index = i + 1; + item.total = len; + item.isFirst = i === 0; + item.isLast = i === len - 1; + buffer += options.fn(item, { data }); + } + return buffer; + } + return options.inverse(this); + }; + helpers2.inArray = function(array, value2, options) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + return util.value(util.indexOf(array, value2) > -1, this, options); + } + return ""; + }; + helpers2.isArray = function(value2) { + return Array.isArray(value2); + }; + helpers2.itemAt = function(array, idx) { + if (util.isUndefined(array)) + return null; + array = util.result(array); + if (Array.isArray(array)) { + idx = !isNaN(idx) ? +idx : 0; + if (idx < 0) { + return array[array.length + idx]; + } + if (idx < array.length) { + return array[idx]; + } + } + return null; + }; + helpers2.join = function(array, separator) { + if (util.isUndefined(array)) + return ""; + if (typeof array === "string") + return array; + array = util.result(array); + if (Array.isArray(array)) { + separator = util.isString(separator) ? separator : ", "; + return array.join(separator); + } + return ""; + }; + helpers2.equalsLength = function(value2, length, options) { + if (util.isOptions(length)) { + options = length; + length = 0; + } + var len = helpers2.length(value2); + return util.value(len === length, this, options); + }; + helpers2.last = function(array, n) { + if (util.isUndefined(array)) + return ""; + if (!Array.isArray(array) && typeof value !== "string") { + return ""; + } + if (isNaN(n)) { + return array[array.length - 1]; + } + return array.slice(-Math.abs(n)); + }; + helpers2.length = function(array) { + if (util.isUndefined(array)) + return 0; + if (util.isObject(array) && !util.isOptions(array)) { + array = Object.keys(array); + } + if (typeof array === "string" && array.startsWith("[") && array.endsWith("]")) { + return array.split(",").length; + } + if (typeof array === "string" || Array.isArray(array)) { + return array.length; + } + return 0; + }; + helpers2.lengthEqual = helpers2.equalsLength; + helpers2.map = function(array, iter) { + if (util.isUndefined(array)) + return ""; + if (!Array.isArray(array)) + return ""; + var len = array.length; + var res = new Array(len); + var i = -1; + if (typeof iter !== "function") { + return array; + } + while (++i < len) { + res[i] = iter(array[i], i, array); + } + return res; + }; + helpers2.pluck = function(array, prop) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + var res = []; + for (var i = 0; i < array.length; i++) { + var val = getValue(array[i], prop); + if (typeof val !== "undefined") { + res.push(val); + } + } + return res; + } + return ""; + }; + helpers2.reverse = function(array) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + array.reverse(); + return array; + } + if (array && typeof array === "string") { + return array.split("").reverse().join(""); + } + return ""; + }; + helpers2.some = function(array, iter, options) { + if (util.isUndefined(array)) + return options.inverse(this); + array = util.result(array); + if (Array.isArray(array)) { + for (var i = 0; i < array.length; i++) { + if (iter(array[i], i, array)) { + return options.fn(this); + } + } + } + return options.inverse(this); + }; + helpers2.sort = function(array, options) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + if (getValue(options, "hash.reverse")) { + return array.sort().reverse(); + } + return array.sort(); + } + return ""; + }; + helpers2.sortBy = function(array, prop, options) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + var args = [].slice.call(arguments); + args.pop(); + if (!util.isString(prop) && typeof prop !== "function") { + return array.sort(); + } + if (typeof prop === "function") { + return array.sort(prop); + } + return array.sort((a, b) => a[prop] > b[prop] ? 1 : -1); + } + return ""; + }; + helpers2.withAfter = function(array, idx, options) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + array = array.slice(idx); + var result = ""; + for (var i = 0; i < array.length; i++) { + result += options.fn(array[i]); + } + return result; + } + return ""; + }; + helpers2.withBefore = function(array, idx, options) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + array = array.slice(0, -idx); + var result = ""; + for (var i = 0; i < array.length; i++) { + result += options.fn(array[i]); + } + return result; + } + return ""; + }; + helpers2.withFirst = function(array, idx, options) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + if (!util.isUndefined(idx)) { + idx = parseFloat(util.result(idx)); + } + if (util.isUndefined(idx)) { + options = idx; + return options.fn(array[0]); + } + array = array.slice(0, idx); + var result = ""; + for (var i = 0; i < array.length; i++) { + result += options.fn(array[i]); + } + return result; + } + return ""; + }; + helpers2.withGroup = function(array, size, options) { + if (util.isUndefined(array)) + return ""; + var result = ""; + array = util.result(array); + if (Array.isArray(array) && array.length > 0) { + var subcontext = []; + for (var i = 0; i < array.length; i++) { + if (i > 0 && i % size === 0) { + result += options.fn(subcontext); + subcontext = []; + } + subcontext.push(array[i]); + } + result += options.fn(subcontext); + } + return result; + }; + helpers2.withLast = function(array, idx, options) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + if (!util.isUndefined(idx)) { + idx = parseFloat(util.result(idx)); + } + if (util.isUndefined(idx)) { + options = idx; + return options.fn(array[array.length - 1]); + } + array = array.slice(-idx); + var len = array.length, i = -1; + var result = ""; + while (++i < len) { + result += options.fn(array[i]); + } + return result; + } + return ""; + }; + helpers2.withSort = function(array, prop, options) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + var result = ""; + if (util.isUndefined(prop)) { + options = prop; + array = array.sort(); + if (getValue(options, "hash.reverse")) { + array = array.reverse(); + } + for (var i = 0, len = array.length; i < len; i++) { + result += options.fn(array[i]); + } + return result; + } + array.sort(function(a, b) { + a = getValue(a, prop); + b = getValue(b, prop); + return a > b ? 1 : a < b ? -1 : 0; + }); + if (getValue(options, "hash.reverse")) { + array = array.reverse(); + } + var alen = array.length, j = -1; + while (++j < alen) { + result += options.fn(array[j]); + } + return result; + } + return ""; + }; + helpers2.unique = function(array, options) { + if (util.isUndefined(array)) + return ""; + array = util.result(array); + if (Array.isArray(array)) { + return array.filter(function(item, index, arr) { + return arr.indexOf(item) === index; + }); + } + return ""; + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/number.js + var require_number = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/number.js"(exports, module) { + "use strict"; + var util = require_handlebars_utils(); + var helpers2 = module.exports; + helpers2.bytes = function(number, precision, options) { + if (number == null) + return "0 B"; + if (isNaN(number)) { + number = number.length; + if (!number) + return "0 B"; + } + if (isNaN(precision)) { + precision = 2; + } + var abbr = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; + precision = Math.pow(10, precision); + number = Number(number); + var len = abbr.length - 1; + while (len-- >= 0) { + var size = Math.pow(10, len * 3); + if (size <= number + 1) { + number = Math.round(number * precision / size) / precision; + number += " " + abbr[len]; + break; + } + } + return number; + }; + helpers2.addCommas = function(num) { + return num.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"); + }; + helpers2.phoneNumber = function(num) { + num = num.toString(); + return "(" + num.substr(0, 3) + ") " + num.substr(3, 3) + "-" + num.substr(6, 4); + }; + helpers2.toAbbr = function(number, precision) { + if (isNaN(number)) { + number = 0; + } + if (util.isUndefined(precision)) { + precision = 2; + } + number = Number(number); + precision = Math.pow(10, precision); + var abbr = ["k", "m", "b", "t", "q"]; + var len = abbr.length - 1; + while (len >= 0) { + var size = Math.pow(10, (len + 1) * 3); + if (size <= number + 1) { + number = Math.round(number * precision / size) / precision; + number += abbr[len]; + break; + } + len--; + } + return number; + }; + helpers2.toExponential = function(number, digits) { + if (isNaN(number)) { + number = 0; + } + if (util.isUndefined(digits)) { + digits = 0; + } + return Number(number).toExponential(digits); + }; + helpers2.toFixed = function(number, digits) { + if (isNaN(number)) { + number = 0; + } + if (isNaN(digits)) { + digits = 0; + } + return Number(number).toFixed(digits); + }; + helpers2.toFloat = function(number) { + return parseFloat(number); + }; + helpers2.toInt = function(number) { + return parseInt(number, 10); + }; + helpers2.toPrecision = function(number, precision) { + if (isNaN(number)) { + number = 0; + } + if (isNaN(precision)) { + precision = 1; + } + return Number(number).toPrecision(precision); + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/url.js + var require_url = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/url.js"(exports, module) { + "use strict"; + var url = __require("url"); + var util = require_handlebars_utils(); + var querystring = __require("querystring"); + var helpers2 = module.exports; + helpers2.encodeURI = function(str) { + if (util.isString(str)) { + return encodeURIComponent(str); + } + }; + helpers2.escape = function(str) { + if (util.isString(str)) { + return querystring.escape(str); + } + }; + helpers2.decodeURI = function(str) { + if (util.isString(str)) { + return decodeURIComponent(str); + } + }; + helpers2.urlResolve = function(base, href) { + return url.resolve(base, href); + }; + helpers2.urlParse = function(str) { + return url.parse(str); + }; + helpers2.stripQuerystring = function(str) { + if (util.isString(str)) { + return str.split("?")[0]; + } + }; + helpers2.stripProtocol = function(str) { + if (util.isString(str)) { + var parsed = url.parse(str); + parsed.protocol = ""; + return parsed.format(); + } + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/string.js + var require_string = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/string.js"(exports, module) { + "use strict"; + var util = require_handlebars_utils(); + var utils = require_utils(); + var helpers2 = module.exports; + helpers2.append = function(str, suffix) { + if (typeof str === "string" && typeof suffix === "string") { + return str + suffix; + } + return str; + }; + helpers2.camelcase = function(str) { + if (typeof str !== "string") + return ""; + return utils.changecase(str, function(ch) { + return ch.toUpperCase(); + }); + }; + helpers2.capitalize = function(str) { + if (typeof str !== "string") + return ""; + return str.charAt(0).toUpperCase() + str.slice(1); + }; + helpers2.capitalizeAll = function(str) { + if (typeof str !== "string") + return ""; + if (util.isString(str)) { + return str.replace(/\w\S*/g, function(word) { + return helpers2.capitalize(word); + }); + } + }; + helpers2.center = function(str, spaces) { + if (typeof str !== "string") + return ""; + var space = ""; + var i = 0; + while (i < spaces) { + space += " "; + i++; + } + return space + str + space; + }; + helpers2.chop = function(str) { + if (typeof str !== "string") + return ""; + return utils.chop(str); + }; + helpers2.dashcase = function(str) { + if (typeof str !== "string") + return ""; + return utils.changecase(str, function(ch) { + return "-" + ch; + }); + }; + helpers2.dotcase = function(str) { + if (typeof str !== "string") + return ""; + return utils.changecase(str, function(ch) { + return "." + ch; + }); + }; + helpers2.downcase = function() { + return helpers2.lowercase.apply(this, arguments); + }; + helpers2.ellipsis = function(str, limit) { + if (util.isString(str)) { + if (str.length <= limit) { + return str; + } + return helpers2.truncate(str, limit) + "\u2026"; + } + }; + helpers2.hyphenate = function(str) { + if (typeof str !== "string") + return ""; + return str.split(" ").join("-"); + }; + helpers2.isString = function(value2) { + return typeof value2 === "string"; + }; + helpers2.lowercase = function(str) { + if (util.isObject(str) && str.fn) { + return str.fn(this).toLowerCase(); + } + if (typeof str !== "string") + return ""; + return str.toLowerCase(); + }; + helpers2.occurrences = function(str, substring) { + if (typeof str !== "string") + return ""; + var len = substring.length; + var pos = 0; + var n = 0; + while ((pos = str.indexOf(substring, pos)) > -1) { + n++; + pos += len; + } + return n; + }; + helpers2.pascalcase = function(str) { + if (typeof str !== "string") + return ""; + str = utils.changecase(str, function(ch) { + return ch.toUpperCase(); + }); + return str.charAt(0).toUpperCase() + str.slice(1); + }; + helpers2.pathcase = function(str) { + if (typeof str !== "string") + return ""; + return utils.changecase(str, function(ch) { + return "/" + ch; + }); + }; + helpers2.plusify = function(str, ch) { + if (typeof str !== "string") + return ""; + if (!util.isString(ch)) + ch = " "; + return str.split(ch).join("+"); + }; + helpers2.prepend = function(str, prefix) { + return typeof str === "string" && typeof prefix === "string" ? prefix + str : str; + }; + helpers2.raw = function(options) { + var str = options.fn(); + var opts = util.options(this, options); + if (opts.escape !== false) { + var idx = 0; + while ((idx = str.indexOf("{{", idx)) !== -1) { + if (str[idx - 1] !== "\\") { + str = str.slice(0, idx) + "\\" + str.slice(idx); + } + idx += 3; + } + } + return str; + }; + helpers2.remove = function(str, ch) { + if (typeof str !== "string") + return ""; + if (!util.isString(ch)) + return str; + return str.split(ch).join(""); + }; + helpers2.removeFirst = function(str, ch) { + if (typeof str !== "string") + return ""; + if (!util.isString(ch)) + return str; + return str.replace(ch, ""); + }; + helpers2.replace = function(str, a, b) { + if (typeof str !== "string") + return ""; + if (!util.isString(a)) + return str; + if (!util.isString(b)) + b = ""; + return str.split(a).join(b); + }; + helpers2.replaceFirst = function(str, a, b) { + if (typeof str !== "string") + return ""; + if (!util.isString(a)) + return str; + if (!util.isString(b)) + b = ""; + return str.replace(a, b); + }; + helpers2.reverse = require_array().reverse; + helpers2.sentence = function(str) { + if (typeof str !== "string") + return ""; + return str.replace(/((?:\S[^\.\?\!]*)[\.\?\!]*)/g, function(txt) { + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + }); + }; + helpers2.snakecase = function(str) { + if (typeof str !== "string") + return ""; + return utils.changecase(str, function(ch) { + return "_" + ch; + }); + }; + helpers2.split = function(str, ch) { + if (typeof str !== "string") + return ""; + if (!util.isString(ch)) + ch = ","; + return str.split(ch); + }; + helpers2.startsWith = function(prefix, str, options) { + var args = [].slice.call(arguments); + options = args.pop(); + if (util.isString(str) && str.indexOf(prefix) === 0) { + return options.fn(this); + } + if (typeof options.inverse === "function") { + return options.inverse(this); + } + return ""; + }; + helpers2.titleize = function(str) { + if (typeof str !== "string") + return ""; + var title = str.replace(/[- _]+/g, " "); + var words = title.split(" "); + var len = words.length; + var res = []; + var i = 0; + while (len--) { + var word = words[i++]; + res.push(exports.capitalize(word)); + } + return res.join(" "); + }; + helpers2.trim = function(str) { + return typeof str === "string" ? str.trim() : ""; + }; + helpers2.trimLeft = function(str) { + if (util.isString(str)) { + return str.replace(/^\s+/, ""); + } + }; + helpers2.trimRight = function(str) { + if (util.isString(str)) { + return str.replace(/\s+$/, ""); + } + }; + helpers2.truncate = function(str, limit, suffix) { + if (util.isString(str)) { + if (typeof suffix !== "string") { + suffix = ""; + } + if (str.length > limit) { + return str.slice(0, limit - suffix.length) + suffix; + } + return str; + } + }; + helpers2.truncateWords = function(str, count, suffix) { + if (util.isString(str) && !isNaN(count)) { + if (typeof suffix !== "string") { + suffix = "\u2026"; + } + var num = Number(count); + var arr = str.split(/[ \t]/); + if (num >= arr.length) { + return str; + } + arr = arr.slice(0, num); + var val = arr.join(" ").trim(); + return val + suffix; + } + }; + helpers2.upcase = function() { + return helpers2.uppercase.apply(this, arguments); + }; + helpers2.uppercase = function(str) { + if (util.isObject(str) && str.fn) { + return str.fn(this).toUpperCase(); + } + if (typeof str !== "string") + return ""; + return str.toUpperCase(); + }; + } + }); + + // ../../node_modules/has-values/index.js + var require_has_values = __commonJS({ + "../../node_modules/has-values/index.js"(exports, module) { + "use strict"; + var typeOf = require_kind_of2(); + module.exports = function has(val) { + switch (typeOf(val)) { + case "boolean": + case "date": + case "function": + case "null": + case "number": + return true; + case "undefined": + return false; + case "regexp": + return val.source !== "(?:)" && val.source !== ""; + case "buffer": + return val.toString() !== ""; + case "error": + return val.message !== ""; + case "string": + case "arguments": + return val.length !== 0; + case "file": + case "map": + case "set": + return val.size !== 0; + case "array": + case "object": + for (const key of Object.keys(val)) { + if (has(val[key])) { + return true; + } + } + return false; + default: { + return true; + } + } + }; + } + }); + + // ../../node_modules/has-value/index.js + var require_has_value = __commonJS({ + "../../node_modules/has-value/index.js"(exports, module) { + "use strict"; + var get = require_get_value(); + var has = require_has_values(); + module.exports = function(obj, path, options) { + if (isObject(obj) && (typeof path === "string" || Array.isArray(path))) { + return has(get(obj, path, options)); + } + return false; + }; + function isObject(val) { + return val != null && (typeof val === "object" || typeof val === "function" || Array.isArray(val)); + } + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/utils/falsey.js + var require_falsey = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/utils/falsey.js"(exports, module) { + "use strict"; + function falsey(val, keywords) { + if (!val) + return true; + let words = keywords || falsey.keywords; + if (!Array.isArray(words)) + words = [words]; + const lower = typeof val === "string" ? val.toLowerCase() : null; + for (const word of words) { + if (word === val) { + return true; + } + if (word === lower) { + return true; + } + } + return false; + } + falsey.keywords = [ + "0", + "false", + "nada", + "nil", + "nay", + "nah", + "negative", + "no", + "none", + "nope", + "nul", + "null", + "nix", + "nyet", + "uh-uh", + "veto", + "zero" + ]; + module.exports = falsey; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/utils/odd.js + var require_odd = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/utils/odd.js"(exports, module) { + "use strict"; + module.exports = function isOdd(value2) { + const n = Math.abs(value2); + if (isNaN(n)) { + throw new TypeError("expected a number"); + } + if (!Number.isInteger(n)) { + throw new Error("expected an integer"); + } + if (!Number.isSafeInteger(n)) { + throw new Error("value exceeds maximum safe integer"); + } + return n % 2 === 1; + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/comparison.js + var require_comparison = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/comparison.js"(exports, module) { + "use strict"; + var has = require_has_value(); + var util = require_handlebars_utils(); + var utils = require_utils(); + var falsey = require_falsey(); + var isOdd = require_odd(); + var helpers2 = module.exports; + helpers2.and = function() { + var len = arguments.length - 1; + var options = arguments[len]; + var val = true; + for (var i = 0; i < len; i++) { + if (!arguments[i]) { + val = false; + break; + } + } + return util.value(val, this, options); + }; + helpers2.compare = function(a, operator, b, options) { + if (arguments.length < 4) { + throw new Error("handlebars Helper {{compare}} expects 4 arguments"); + } + var result; + switch (operator) { + case "==": + result = a == b; + break; + case "===": + result = a === b; + break; + case "!=": + result = a != b; + break; + case "!==": + result = a !== b; + break; + case "<": + result = a < b; + break; + case ">": + result = a > b; + break; + case "<=": + result = a <= b; + break; + case ">=": + result = a >= b; + break; + case "typeof": + result = typeof a === b; + break; + default: { + throw new Error( + "helper {{compare}}: invalid operator: `" + operator + "`" + ); + } + } + return util.value(result, this, options); + }; + helpers2.contains = function(collection, value2, startIndex, options) { + if (typeof startIndex === "object") { + options = startIndex; + startIndex = void 0; + } + var val = utils.contains(collection, value2, startIndex); + return util.value(val, this, options); + }; + helpers2.default = function() { + for (var i = 0; i < arguments.length - 1; i++) { + if (arguments[i] != null) + return arguments[i]; + } + return ""; + }; + helpers2.eq = function(a, b, options) { + if (arguments.length === 2) { + options = b; + b = options.hash.compare; + } + return util.value(a === b, this, options); + }; + helpers2.gt = function(a, b, options) { + if (arguments.length === 2) { + options = b; + b = options.hash.compare; + } + return util.value(a > b, this, options); + }; + helpers2.gte = function(a, b, options) { + if (arguments.length === 2) { + options = b; + b = options.hash.compare; + } + return util.value(a >= b, this, options); + }; + helpers2.has = function(value2, pattern, options) { + if (util.isOptions(value2)) { + options = value2; + pattern = null; + value2 = null; + } + if (util.isOptions(pattern)) { + options = pattern; + pattern = null; + } + if (value2 === null) { + return util.value(false, this, options); + } + if (arguments.length === 2) { + return util.value(has(this, value2), this, options); + } + if ((Array.isArray(value2) || util.isString(value2)) && util.isString(pattern)) { + if (value2.indexOf(pattern) > -1) { + return util.fn(true, this, options); + } + } + if (util.isObject(value2) && util.isString(pattern) && pattern in value2) { + return util.fn(true, this, options); + } + return util.inverse(false, this, options); + }; + helpers2.isFalsey = function(val, options) { + return util.value(falsey(val), this, options); + }; + helpers2.isTruthy = function(val, options) { + return util.value(!falsey(val), this, options); + }; + helpers2.ifEven = function(num, options) { + return util.value(!isOdd(num), this, options); + }; + helpers2.ifNth = function(a, b, options) { + var isNth = !isNaN(a) && !isNaN(b) && b % a === 0; + return util.value(isNth, this, options); + }; + helpers2.ifOdd = function(val, options) { + return util.value(isOdd(val), this, options); + }; + helpers2.is = function(a, b, options) { + if (arguments.length === 2) { + options = b; + b = options.hash.compare; + } + return util.value(a == b, this, options); + }; + helpers2.isnt = function(a, b, options) { + if (arguments.length === 2) { + options = b; + b = options.hash.compare; + } + return util.value(a != b, this, options); + }; + helpers2.lt = function(a, b, options) { + if (arguments.length === 2) { + options = b; + b = options.hash.compare; + } + return util.value(a < b, this, options); + }; + helpers2.lte = function(a, b, options) { + if (arguments.length === 2) { + options = b; + b = options.hash.compare; + } + return util.value(a <= b, this, options); + }; + helpers2.neither = function(a, b, options) { + return util.value(!a && !b, this, options); + }; + helpers2.not = function(val, options) { + return util.value(!val, this, options); + }; + helpers2.or = function() { + var len = arguments.length - 1; + var options = arguments[len]; + var val = false; + for (var i = 0; i < len; i++) { + if (arguments[i]) { + val = true; + break; + } + } + return util.value(val, this, options); + }; + helpers2.unlessEq = function(a, b, options) { + if (util.isOptions(b)) { + options = b; + b = options.hash.compare; + } + return util.value(a !== b, this, options); + }; + helpers2.unlessGt = function(a, b, options) { + if (util.isOptions(b)) { + options = b; + b = options.hash.compare; + } + return util.value(a <= b, this, options); + }; + helpers2.unlessLt = function(a, b, options) { + if (util.isOptions(b)) { + options = b; + b = options.hash.compare; + } + return util.value(a >= b, this, options); + }; + helpers2.unlessGteq = function(a, b, options) { + if (util.isOptions(b)) { + options = b; + b = options.hash.compare; + } + return util.value(a < b, this, options); + }; + helpers2.unlessLteq = function(a, b, options) { + if (util.isOptions(b)) { + options = b; + b = options.hash.compare; + } + return util.value(a > b, this, options); + }; + } + }); + + // ../../node_modules/is-number/node_modules/kind-of/index.js + var require_kind_of3 = __commonJS({ + "../../node_modules/is-number/node_modules/kind-of/index.js"(exports, module) { + var isBuffer = require_is_buffer(); + var toString = Object.prototype.toString; + module.exports = function kindOf(val) { + if (typeof val === "undefined") { + return "undefined"; + } + if (val === null) { + return "null"; + } + if (val === true || val === false || val instanceof Boolean) { + return "boolean"; + } + if (typeof val === "string" || val instanceof String) { + return "string"; + } + if (typeof val === "number" || val instanceof Number) { + return "number"; + } + if (typeof val === "function" || val instanceof Function) { + return "function"; + } + if (typeof Array.isArray !== "undefined" && Array.isArray(val)) { + return "array"; + } + if (val instanceof RegExp) { + return "regexp"; + } + if (val instanceof Date) { + return "date"; + } + var type = toString.call(val); + if (type === "[object RegExp]") { + return "regexp"; + } + if (type === "[object Date]") { + return "date"; + } + if (type === "[object Arguments]") { + return "arguments"; + } + if (type === "[object Error]") { + return "error"; + } + if (isBuffer(val)) { + return "buffer"; + } + if (type === "[object Set]") { + return "set"; + } + if (type === "[object WeakSet]") { + return "weakset"; + } + if (type === "[object Map]") { + return "map"; + } + if (type === "[object WeakMap]") { + return "weakmap"; + } + if (type === "[object Symbol]") { + return "symbol"; + } + if (type === "[object Int8Array]") { + return "int8array"; + } + if (type === "[object Uint8Array]") { + return "uint8array"; + } + if (type === "[object Uint8ClampedArray]") { + return "uint8clampedarray"; + } + if (type === "[object Int16Array]") { + return "int16array"; + } + if (type === "[object Uint16Array]") { + return "uint16array"; + } + if (type === "[object Int32Array]") { + return "int32array"; + } + if (type === "[object Uint32Array]") { + return "uint32array"; + } + if (type === "[object Float32Array]") { + return "float32array"; + } + if (type === "[object Float64Array]") { + return "float64array"; + } + return "object"; + }; + } + }); + + // ../../node_modules/is-number/index.js + var require_is_number = __commonJS({ + "../../node_modules/is-number/index.js"(exports, module) { + "use strict"; + var typeOf = require_kind_of3(); + module.exports = function isNumber(num) { + var type = typeOf(num); + if (type !== "number" && type !== "string") { + return false; + } + var n = +num; + return n - n + 1 >= 0 && num !== ""; + }; + } + }); + + // ../../node_modules/get-object/index.js + var require_get_object = __commonJS({ + "../../node_modules/get-object/index.js"(exports, module) { + "use strict"; + var isNumber = require_is_number(); + module.exports = function getObject(obj, prop) { + if (!prop) + return obj; + if (!obj) + return {}; + var segs = String(prop).split(/[[.\]]/).filter(Boolean); + var last = segs[segs.length - 1], res = {}; + while (prop = segs.shift()) { + obj = obj[prop]; + if (!obj) + return {}; + } + if (isNumber(last)) + return [obj]; + res[last] = obj; + return res; + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/object.js + var require_object = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/object.js"(exports, module) { + "use strict"; + var hasOwn = Object.hasOwnProperty; + var util = require_handlebars_utils(); + var array = require_array(); + var helpers2 = module.exports; + var getValue = require_get_value(); + var getObject = require_get_object(); + var createFrame = require_createFrame(); + helpers2.extend = function() { + var args = [].slice.call(arguments); + var opts = {}; + if (util.isOptions(args[args.length - 1])) { + opts = args.pop().hash; + args.push(opts); + } + var context = {}; + for (var i = 0; i < args.length; i++) { + var obj = args[i]; + if (util.isObject(obj)) { + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; j++) { + var key = keys[j]; + context[key] = obj[key]; + } + } + } + return context; + }; + helpers2.forIn = function(obj, options) { + if (!util.isOptions(options)) { + return obj.inverse(this); + } + var data = createFrame(options, options.hash); + var result = ""; + for (var key in obj) { + data.key = key; + result += options.fn(obj[key], { data }); + } + return result; + }; + helpers2.forOwn = function(obj, options) { + if (!util.isOptions(options)) { + return obj.inverse(this); + } + var data = createFrame(options, options.hash); + var result = ""; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + data.key = key; + result += options.fn(obj[key], { data }); + } + } + return result; + }; + helpers2.toPath = function() { + var prop = []; + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] === "string" || typeof arguments[i] === "number") { + prop.push(arguments[i]); + } + } + return prop.join("."); + }; + helpers2.get = function(prop, context, options) { + var val = getValue(context, prop); + if (options && options.fn) { + return val ? options.fn(val) : options.inverse(context); + } + return val; + }; + helpers2.getObject = function(prop, context) { + return getObject(context, prop); + }; + helpers2.hasOwn = function(context, key) { + return hasOwn.call(context, key); + }; + helpers2.isObject = function(value2) { + return typeof value2 === "object"; + }; + helpers2.JSONparse = function(str, options) { + return JSON.parse(str); + }; + helpers2.JSONstringify = function(obj, indent) { + if (isNaN(indent)) { + indent = 0; + } + return JSON.stringify(obj, null, indent); + }; + helpers2.merge = function(context) { + var args = [].slice.call(arguments); + var opts = {}; + if (util.isOptions(args[args.length - 1])) { + opts = args.pop().hash; + args.push(opts); + } + return Object.assign.apply(null, args); + }; + helpers2.parseJSON = helpers2.JSONparse; + helpers2.pick = function(props, context, options) { + var keys = array.arrayify(props); + var len = keys.length, i = -1; + var result = {}; + while (++i < len) { + result = helpers2.extend({}, result, getObject(context, keys[i])); + } + if (options.fn) { + if (Object.keys(result).length) { + return options.fn(result); + } + return options.inverse(context); + } + return result; + }; + helpers2.stringify = helpers2.JSONstringify; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/regex.js + var require_regex = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/regex.js"(exports, module) { + "use strict"; + var util = require_handlebars_utils(); + var helpers2 = module.exports; + var kindOf = require_kind_of2(); + helpers2.toRegex = function(str, locals, options) { + var opts = util.options({}, locals, options); + return new RegExp(str, opts.flags); + }; + helpers2.test = function(str, regex) { + if (typeof str !== "string") { + return false; + } + if (kindOf(regex) !== "regexp") { + throw new TypeError("expected a regular expression"); + } + return regex.test(str); + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/rng.js + function rng() { + if (poolPtr > rnds8Pool.length - 16) { + import_crypto.default.randomFillSync(rnds8Pool); + poolPtr = 0; + } + return rnds8Pool.slice(poolPtr, poolPtr += 16); + } + var import_crypto, rnds8Pool, poolPtr; + var init_rng = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/rng.js"() { + import_crypto = __toESM(__require("crypto")); + rnds8Pool = new Uint8Array(256); + poolPtr = rnds8Pool.length; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/regex.js + var regex_default; + var init_regex = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/regex.js"() { + regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/validate.js + function validate(uuid) { + return typeof uuid === "string" && regex_default.test(uuid); + } + var validate_default; + var init_validate = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/validate.js"() { + init_regex(); + validate_default = validate; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/stringify.js + function unsafeStringify(arr, offset = 0) { + return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; + } + function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); + if (!validate_default(uuid)) { + throw TypeError("Stringified UUID is invalid"); + } + return uuid; + } + var byteToHex, stringify_default; + var init_stringify = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/stringify.js"() { + init_validate(); + byteToHex = []; + for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 256).toString(16).slice(1)); + } + stringify_default = stringify; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v1.js + function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== void 0 ? options.clockseq : _clockseq; + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || rng)(); + if (node == null) { + node = _nodeId = [seedBytes[0] | 1, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + if (clockseq == null) { + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 16383; + } + } + let msecs = options.msecs !== void 0 ? options.msecs : Date.now(); + let nsecs = options.nsecs !== void 0 ? options.nsecs : _lastNSecs + 1; + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 1e4; + if (dt < 0 && options.clockseq === void 0) { + clockseq = clockseq + 1 & 16383; + } + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === void 0) { + nsecs = 0; + } + if (nsecs >= 1e4) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; + msecs += 122192928e5; + const tl = ((msecs & 268435455) * 1e4 + nsecs) % 4294967296; + b[i++] = tl >>> 24 & 255; + b[i++] = tl >>> 16 & 255; + b[i++] = tl >>> 8 & 255; + b[i++] = tl & 255; + const tmh = msecs / 4294967296 * 1e4 & 268435455; + b[i++] = tmh >>> 8 & 255; + b[i++] = tmh & 255; + b[i++] = tmh >>> 24 & 15 | 16; + b[i++] = tmh >>> 16 & 255; + b[i++] = clockseq >>> 8 | 128; + b[i++] = clockseq & 255; + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + return buf || unsafeStringify(b); + } + var _nodeId, _clockseq, _lastMSecs, _lastNSecs, v1_default; + var init_v1 = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v1.js"() { + init_rng(); + init_stringify(); + _lastMSecs = 0; + _lastNSecs = 0; + v1_default = v1; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/parse.js + function parse(uuid) { + if (!validate_default(uuid)) { + throw TypeError("Invalid UUID"); + } + let v; + const arr = new Uint8Array(16); + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 255; + arr[2] = v >>> 8 & 255; + arr[3] = v & 255; + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 255; + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 255; + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 255; + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255; + arr[11] = v / 4294967296 & 255; + arr[12] = v >>> 24 & 255; + arr[13] = v >>> 16 & 255; + arr[14] = v >>> 8 & 255; + arr[15] = v & 255; + return arr; + } + var parse_default; + var init_parse = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/parse.js"() { + init_validate(); + parse_default = parse; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v35.js + function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); + const bytes = []; + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + return bytes; + } + function v35(name, version2, hashfunc) { + function generateUUID(value2, namespace, buf, offset) { + var _namespace; + if (typeof value2 === "string") { + value2 = stringToBytes(value2); + } + if (typeof namespace === "string") { + namespace = parse_default(namespace); + } + if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { + throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)"); + } + let bytes = new Uint8Array(16 + value2.length); + bytes.set(namespace); + bytes.set(value2, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 15 | version2; + bytes[8] = bytes[8] & 63 | 128; + if (buf) { + offset = offset || 0; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + return buf; + } + return unsafeStringify(bytes); + } + try { + generateUUID.name = name; + } catch (err) { + } + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; + } + var DNS, URL; + var init_v35 = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v35.js"() { + init_stringify(); + init_parse(); + DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; + URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/md5.js + function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return import_crypto2.default.createHash("md5").update(bytes).digest(); + } + var import_crypto2, md5_default; + var init_md5 = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/md5.js"() { + import_crypto2 = __toESM(__require("crypto")); + md5_default = md5; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v3.js + var v3, v3_default; + var init_v3 = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v3.js"() { + init_v35(); + init_md5(); + v3 = v35("v3", 48, md5_default); + v3_default = v3; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/native.js + var import_crypto3, native_default; + var init_native = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/native.js"() { + import_crypto3 = __toESM(__require("crypto")); + native_default = { + randomUUID: import_crypto3.default.randomUUID + }; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v4.js + function v4(options, buf, offset) { + if (native_default.randomUUID && !buf && !options) { + return native_default.randomUUID(); + } + options = options || {}; + const rnds = options.random || (options.rng || rng)(); + rnds[6] = rnds[6] & 15 | 64; + rnds[8] = rnds[8] & 63 | 128; + if (buf) { + offset = offset || 0; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + return buf; + } + return unsafeStringify(rnds); + } + var v4_default; + var init_v4 = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v4.js"() { + init_native(); + init_rng(); + init_stringify(); + v4_default = v4; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/sha1.js + function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === "string") { + bytes = Buffer.from(bytes, "utf8"); + } + return import_crypto4.default.createHash("sha1").update(bytes).digest(); + } + var import_crypto4, sha1_default; + var init_sha1 = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/sha1.js"() { + import_crypto4 = __toESM(__require("crypto")); + sha1_default = sha1; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v5.js + var v5, v5_default; + var init_v5 = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v5.js"() { + init_v35(); + init_sha1(); + v5 = v35("v5", 80, sha1_default); + v5_default = v5; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/nil.js + var nil_default; + var init_nil = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/nil.js"() { + nil_default = "00000000-0000-0000-0000-000000000000"; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/version.js + function version(uuid) { + if (!validate_default(uuid)) { + throw TypeError("Invalid UUID"); + } + return parseInt(uuid.slice(14, 15), 16); + } + var version_default; + var init_version = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/version.js"() { + init_validate(); + version_default = version; + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/index.js + var esm_node_exports = {}; + __export(esm_node_exports, { + NIL: () => nil_default, + parse: () => parse_default, + stringify: () => stringify_default, + v1: () => v1_default, + v3: () => v3_default, + v4: () => v4_default, + v5: () => v5_default, + validate: () => validate_default, + version: () => version_default + }); + var init_esm_node = __esm({ + "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/index.js"() { + init_v1(); + init_v3(); + init_v4(); + init_v5(); + init_nil(); + init_version(); + init_validate(); + init_stringify(); + init_parse(); + } + }); + + // ../../node_modules/@budibase/handlebars-helpers/lib/uuid.js + var require_uuid = __commonJS({ + "../../node_modules/@budibase/handlebars-helpers/lib/uuid.js"(exports, module) { + var uuid = (init_esm_node(), __toCommonJS(esm_node_exports)); + var helpers2 = module.exports; + helpers2.uuid = function() { + return uuid.v4(); + }; + } + }); + + // ../string-templates/src/helpers/list.js + var require_list = __commonJS({ + "../string-templates/src/helpers/list.js"(exports, module) { + var { date, duration } = require_date(); + var externalCollections = { + math: require_math(), + array: require_array(), + number: require_number(), + url: require_url(), + string: require_string(), + comparison: require_comparison(), + object: require_object(), + regex: require_regex(), + uuid: require_uuid() + }; + var helpersToRemoveForJs = ["sortBy"]; + module.exports.helpersToRemoveForJs = helpersToRemoveForJs; + var addedHelpers = { + date, + duration + }; + var helpers2 = void 0; + module.exports.getJsHelperList = () => { + if (helpers2) { + return helpers2; + } + helpers2 = {}; + for (let collection of Object.values(externalCollections)) { + for (let [key, func] of Object.entries(collection)) { + helpers2[key] = (...props) => func(...props, {}); + } + } + for (let key of Object.keys(addedHelpers)) { + helpers2[key] = addedHelpers[key]; + } + for (const toRemove of helpersToRemoveForJs) { + delete helpers2[toRemove]; + } + Object.freeze(helpers2); + return helpers2; + }; + } + }); + + // src/jsRunner/bundles/index-helpers.ts + var { + getJsHelperList + } = require_list(); + var helpers = { + ...getJsHelperList(), + // pointing stripProtocol to a unexisting function to be able to declare it on isolated-vm + // @ts-ignore + // eslint-disable-next-line no-undef + stripProtocol: helpersStripProtocol + }; + + return helpers +})(); /*! Bundled license information: is-buffer/index.js: diff --git a/packages/server/src/jsRunner/bundles/index-helpers.ts b/packages/server/src/jsRunner/bundles/index-helpers.ts index fc3c860f20..91b9c8e821 100644 --- a/packages/server/src/jsRunner/bundles/index-helpers.ts +++ b/packages/server/src/jsRunner/bundles/index-helpers.ts @@ -2,9 +2,8 @@ const { getJsHelperList, } = require("../../../../string-templates/src/helpers/list.js") -const helpers = getJsHelperList() -export default { - ...helpers, +export const helpers = { + ...getJsHelperList(), // pointing stripProtocol to a unexisting function to be able to declare it on isolated-vm // @ts-ignore // eslint-disable-next-line no-undef diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index ab26f3f6d1..5471747fdf 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -16,31 +16,14 @@ class ExecutionTimeoutError extends Error { } class ModuleHandler { - private modules: { - import: string - moduleKey: string - module: ivm.Module - }[] = [] + private modules: string[] = [] - private generateRandomKey = () => `i${crypto.randomUUID().replace(/-/g, "")}` - - registerModule(module: ivm.Module, imports: string) { - this.modules.push({ - moduleKey: this.generateRandomKey(), - import: imports, - module: module, - }) + registerModule(code: string) { + this.modules.push(code) } generateImports() { - return this.modules - .map(m => `import ${m.import} from "${m.moduleKey}"`) - .join(";") - } - - getModule(key: string) { - const module = this.modules.find(m => m.moduleKey === key) - return module?.module + return this.modules.join(";") } } @@ -98,34 +81,39 @@ export class IsolatedVM implements VM { }), }) + const cryptoModule = this.registerCallbacks({ + randomUUID: crypto.randomUUID, + }) + const injectedRequire = `const require=function req(val) { switch (val) { case "url": return ${urlModule}; case "querystring": return ${querystringModule}; + case "crypto": return ${cryptoModule}; } }` const helpersSource = loadBundle(BundleType.HELPERS) - const helpersModule = this.isolate.compileModuleSync( - `${injectedRequire};${helpersSource}` - ) + // const helpersModule = this.isolate.compileModuleSync( + // `${injectedRequire};${helpersSource}` + // ) - helpersModule.instantiateSync(this.vm, specifier => { - if (specifier === "crypto") { - const cryptoModule = this.registerCallbacks({ - randomUUID: crypto.randomUUID, - }) - const module = this.isolate.compileModuleSync( - `export default ${cryptoModule}` - ) - module.instantiateSync(this.vm, specifier => { - throw new Error(`No imports allowed. Required: ${specifier}`) - }) - return module - } - throw new Error(`No imports allowed. Required: ${specifier}`) - }) + // helpersModule.instantiateSync(this.vm, specifier => { + // if (specifier === "crypto") { + // const cryptoModule = this.registerCallbacks({ + // randomUUID: crypto.randomUUID, + // }) + // const module = this.isolate.compileModuleSync( + // `export default ${cryptoModule}` + // ) + // module.instantiateSync(this.vm, specifier => { + // throw new Error(`No imports allowed. Required: ${specifier}`) + // }) + // return module + // } + // throw new Error(`No imports allowed. Required: ${specifier}`) + // }) - this.moduleHandler.registerModule(helpersModule, "helpers") + this.moduleHandler.registerModule(`${injectedRequire};${helpersSource}`) return this } @@ -191,7 +179,11 @@ export class IsolatedVM implements VM { throw new Error(`No imports allowed. Required: ${specifier}`) }) - this.moduleHandler.registerModule(bsonModule, "{deserialize, toJson}") + this.moduleHandler.registerModule( + bsonModule, + "{deserialize, toJson}", + "bson" + ) return this } @@ -206,25 +198,13 @@ export class IsolatedVM implements VM { } } - code = `${this.moduleHandler.generateImports()};results.out=${this.codeWrapper( - code - )};` + code = `${this.moduleHandler.generateImports()};${this.codeWrapper(code)};` - const script = this.isolate.compileModuleSync(code) + const script = this.isolate.compileScriptSync(code) - script.instantiateSync(this.vm, specifier => { - const module = this.moduleHandler.getModule(specifier) - if (module) { - return module - } + const result = script.runSync(this.vm, { timeout: this.invocationTimeout }) - throw new Error(`"${specifier}" import not allowed`) - }) - - script.evaluateSync({ timeout: this.invocationTimeout }) - - const result = this.getFromContext(this.resultKey) - return result.out + return result } private registerCallbacks(functions: Record) { @@ -260,11 +240,4 @@ export class IsolatedVM implements VM { ) } } - - private getFromContext(key: string) { - const ref = this.vm.global.getSync(key, { reference: true }) - const result = ref.copySync() - ref.release() - return result - } } From f03d9a01783df46b4780d0c66d7c7e963a114f19 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 16:30:02 +0100 Subject: [PATCH 029/213] Clean --- packages/server/src/jsRunner/vm/index.ts | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index 5471747fdf..ac01a52a6e 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -93,26 +93,6 @@ export class IsolatedVM implements VM { } }` const helpersSource = loadBundle(BundleType.HELPERS) - // const helpersModule = this.isolate.compileModuleSync( - // `${injectedRequire};${helpersSource}` - // ) - - // helpersModule.instantiateSync(this.vm, specifier => { - // if (specifier === "crypto") { - // const cryptoModule = this.registerCallbacks({ - // randomUUID: crypto.randomUUID, - // }) - // const module = this.isolate.compileModuleSync( - // `export default ${cryptoModule}` - // ) - // module.instantiateSync(this.vm, specifier => { - // throw new Error(`No imports allowed. Required: ${specifier}`) - // }) - // return module - // } - // throw new Error(`No imports allowed. Required: ${specifier}`) - // }) - this.moduleHandler.registerModule(`${injectedRequire};${helpersSource}`) return this } From be69edffd782f807c61b53f1f009770d4e905544 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 16:36:21 +0100 Subject: [PATCH 030/213] Fix bson --- .../src/jsRunner/bundles/bson.ivm.bundle.js | 3801 ++++++++++++++++- .../src/jsRunner/bundles/bsonPackage.ts | 8 +- packages/server/src/jsRunner/vm/index.ts | 39 +- 3 files changed, 3819 insertions(+), 29 deletions(-) diff --git a/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js b/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js index b23efa87d1..f83c062429 100644 --- a/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js +++ b/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js @@ -1,7 +1,3794 @@ -function kt(e){return["[object ArrayBuffer]","[object SharedArrayBuffer]"].includes(Object.prototype.toString.call(e))}function Lt(e){return Object.prototype.toString.call(e)==="[object Uint8Array]"}function qt(e){return Object.prototype.toString.call(e)==="[object RegExp]"}function Rt(e){return Object.prototype.toString.call(e)==="[object Map]"}function Zt(e){return Object.prototype.toString.call(e)==="[object Date]"}function j(e,t){return JSON.stringify(e,(n,s)=>typeof s=="bigint"?{$numberLong:`${s}`}:Rt(s)?Object.fromEntries(s):s)}function Kt(e){if(e!=null&&typeof e=="object"&&"stylize"in e&&typeof e.stylize=="function")return e.stylize}var mt=6,Dt=2147483647,jt=-2147483648,zt=Math.pow(2,63)-1,Ft=-Math.pow(2,63),Gt=Math.pow(2,53),Xt=-Math.pow(2,53),wt=1,Qt=2,vt=3,te=4,ee=5,ne=6,se=7,re=8,ie=9,oe=10,pt=11,fe=12,le=13,ce=14,he=15,St=16,ae=17,ge=18,ue=19,ye=255,me=127;var ct=4,cn=Object.freeze({double:1,string:2,object:3,array:4,binData:5,undefined:6,objectId:7,bool:8,date:9,null:10,regex:11,dbPointer:12,javascript:13,symbol:14,javascriptWithScope:15,int:16,timestamp:17,long:18,decimal:19,minKey:-1,maxKey:127}),o=class extends Error{get bsonError(){return!0}get name(){return"BSONError"}constructor(t,n){super(t,n)}static isBSONError(t){return t!=null&&typeof t=="object"&&"bsonError"in t&&t.bsonError===!0&&"name"in t&&"message"in t&&"stack"in t}},yt=class extends o{get name(){return"BSONVersionError"}constructor(){super(`Unsupported BSON version, bson types must be from bson ${mt}.x.x`)}},ht=class extends o{get name(){return"BSONRuntimeError"}constructor(t){super(t)}},we=128,pe=192,Se=224,Ne=240,Be=248,Oe=192,be=224,Ee=240,Te=128;function Mt(e,t,n){let s=0;for(let r=t;r20)return null;if(s===1&&e[t]<128)return String.fromCharCode(e[t]);if(s===2&&e[t]<128&&e[t+1]<128)return String.fromCharCode(e[t])+String.fromCharCode(e[t+1]);if(s===3&&e[t]<128&&e[t+1]<128&&e[t+2]<128)return String.fromCharCode(e[t])+String.fromCharCode(e[t+1])+String.fromCharCode(e[t+2]);let r=[];for(let i=t;i127)return null;r.push(u)}return String.fromCharCode(...r)}function Ie(e){return C.fromNumberArray(Array.from({length:e},()=>Math.floor(Math.random()*256)))}var de=await(async()=>{try{return(await import("crypto")).randomBytes}catch{return Ie}})(),C={toLocalBufferType(e){if(Buffer.isBuffer(e))return e;if(ArrayBuffer.isView(e))return Buffer.from(e.buffer,e.byteOffset,e.byteLength);let t=e?.[Symbol.toStringTag]??Object.prototype.toString.call(e);if(t==="ArrayBuffer"||t==="SharedArrayBuffer"||t==="[object ArrayBuffer]"||t==="[object SharedArrayBuffer]")return Buffer.from(e);throw new o(`Cannot create Buffer from ${String(e)}`)},allocate(e){return Buffer.alloc(e)},equals(e,t){return C.toLocalBufferType(e).equals(t)},fromNumberArray(e){return Buffer.from(e)},fromBase64(e){return Buffer.from(e,"base64")},toBase64(e){return C.toLocalBufferType(e).toString("base64")},fromISO88591(e){return Buffer.from(e,"binary")},toISO88591(e){return C.toLocalBufferType(e).toString("binary")},fromHex(e){return Buffer.from(e,"hex")},toHex(e){return C.toLocalBufferType(e).toString("hex")},fromUTF8(e){return Buffer.from(e,"utf8")},toUTF8(e,t,n,s){let r=n-t<=20?xt(e,t,n):null;if(r!=null)return r;let i=C.toLocalBufferType(e).toString("utf8",t,n);if(s){for(let u=0;uMath.floor(Math.random()*256)))}var _e=(()=>{let{crypto:e}=globalThis;if(e!=null&&typeof e.getRandomValues=="function")return t=>e.getRandomValues(X.allocate(t));if($e()){let{console:t}=globalThis;t?.warn?.("BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.")}return Ae})(),Nt=/(\d|[a-f])/i,X={toLocalBufferType(e){let t=e?.[Symbol.toStringTag]??Object.prototype.toString.call(e);if(t==="Uint8Array")return e;if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength));if(t==="ArrayBuffer"||t==="SharedArrayBuffer"||t==="[object ArrayBuffer]"||t==="[object SharedArrayBuffer]")return new Uint8Array(e);throw new o(`Cannot make a Uint8Array from ${String(e)}`)},allocate(e){if(typeof e!="number")throw new TypeError(`The "size" argument must be of type number. Received ${String(e)}`);return new Uint8Array(e)},equals(e,t){if(e.byteLength!==t.byteLength)return!1;for(let n=0;nt.charCodeAt(0))},toBase64(e){return btoa(X.toISO88591(e))},fromISO88591(e){return Uint8Array.from(e,t=>t.charCodeAt(0)&255)},toISO88591(e){return Array.from(Uint16Array.from(e),t=>String.fromCharCode(t)).join("")},fromHex(e){let t=e.length%2===0?e:e.slice(0,e.length-1),n=[];for(let s=0;st.toString(16).padStart(2,"0")).join("")},fromUTF8(e){return new TextEncoder().encode(e)},toUTF8(e,t,n,s){let r=n-t<=20?xt(e,t,n):null;if(r!=null)return r;if(s)try{return new TextDecoder("utf8",{fatal:s}).decode(e.slice(t,n))}catch(i){throw new o("Invalid UTF-8 string in BSON document",{cause:i})}return new TextDecoder("utf8",{fatal:s}).decode(e.slice(t,n))},utf8ByteLength(e){return X.fromUTF8(e).byteLength},encodeUTF8Into(e,t,n){let s=X.fromUTF8(t);return e.set(s,n),s.byteLength},randomBytes:_e},Ue=typeof Buffer=="function"&&Buffer.prototype?._isBuffer!==!0,h=Ue?C:X,Q=class extends DataView{static fromUint8Array(t){return new DataView(t.buffer,t.byteOffset,t.byteLength)}},D=class{get[Symbol.for("@@mdb.bson.version")](){return mt}[Symbol.for("nodejs.util.inspect.custom")](t,n,s){return this.inspect(t,n,s)}},_=class e extends D{get _bsontype(){return"Binary"}constructor(t,n){if(super(),t!=null&&typeof t=="string"&&!ArrayBuffer.isView(t)&&!kt(t)&&!Array.isArray(t))throw new o("Binary can only be constructed from Uint8Array or number[]");this.sub_type=n??e.BSON_BINARY_SUBTYPE_DEFAULT,t==null?(this.buffer=h.allocate(e.BUFFER_SIZE),this.position=0):(this.buffer=Array.isArray(t)?h.fromNumberArray(t):h.toLocalBufferType(t),this.position=this.buffer.byteLength)}put(t){if(typeof t=="string"&&t.length!==1)throw new o("only accepts single character String");if(typeof t!="number"&&t.length!==1)throw new o("only accepts single character Uint8Array or Array");let n;if(typeof t=="string"?n=t.charCodeAt(0):typeof t=="number"?n=t:n=t[0],n<0||n>255)throw new o("only accepts number in a valid unsigned byte range 0-255");if(this.buffer.byteLength>this.position)this.buffer[this.position++]=n;else{let s=h.allocate(e.BUFFER_SIZE+this.buffer.length);s.set(this.buffer,0),this.buffer=s,this.buffer[this.position++]=n}}write(t,n){if(n=typeof n=="number"?n:this.position,this.buffer.byteLengththis.position?n+t.length:this.position;else if(typeof t=="string")throw new o("input cannot be string")}read(t,n){return n=n&&n>0?n:this.position,this.buffer.slice(t,t+n)}value(){return this.buffer.length===this.position?this.buffer:this.buffer.subarray(0,this.position)}length(){return this.position}toJSON(){return h.toBase64(this.buffer)}toString(t){return t==="hex"?h.toHex(this.buffer):t==="base64"?h.toBase64(this.buffer):t==="utf8"||t==="utf-8"?h.toUTF8(this.buffer,0,this.buffer.byteLength,!1):h.toUTF8(this.buffer,0,this.buffer.byteLength,!1)}toExtendedJSON(t){t=t||{};let n=h.toBase64(this.buffer),s=Number(this.sub_type).toString(16);return t.legacy?{$binary:n,$type:s.length===1?"0"+s:s}:{$binary:{base64:n,subType:s.length===1?"0"+s:s}}}toUUID(){if(this.sub_type===e.SUBTYPE_UUID)return new W(this.buffer.slice(0,this.position));throw new o(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${e.SUBTYPE_UUID}" is currently supported.`)}static createFromHexString(t,n){return new e(h.fromHex(t),n)}static createFromBase64(t,n){return new e(h.fromBase64(t),n)}static fromExtendedJSON(t,n){n=n||{};let s,r;if("$binary"in t?n.legacy&&typeof t.$binary=="string"&&"$type"in t?(r=t.$type?parseInt(t.$type,16):0,s=h.fromBase64(t.$binary)):typeof t.$binary!="string"&&(r=t.$binary.subType?parseInt(t.$binary.subType,16):0,s=h.fromBase64(t.$binary.base64)):"$uuid"in t&&(r=4,s=W.bytesFromString(t.$uuid)),!s)throw new o(`Unexpected Binary Extended JSON format ${JSON.stringify(t)}`);return r===ct?new W(s):new e(s,r)}inspect(t,n,s){s??=j;let r=h.toBase64(this.buffer.subarray(0,this.position)),i=s(r,n),u=s(this.sub_type,n);return`Binary.createFromBase64(${i}, ${u})`}};_.BSON_BINARY_SUBTYPE_DEFAULT=0;_.BUFFER_SIZE=256;_.SUBTYPE_DEFAULT=0;_.SUBTYPE_FUNCTION=1;_.SUBTYPE_BYTE_ARRAY=2;_.SUBTYPE_UUID_OLD=3;_.SUBTYPE_UUID=4;_.SUBTYPE_MD5=5;_.SUBTYPE_ENCRYPTED=6;_.SUBTYPE_COLUMN=7;_.SUBTYPE_USER_DEFINED=128;var gt=16,Le=/^[0-9A-F]{32}$/i,Re=/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i,W=class e extends _{constructor(t){let n;if(t==null)n=e.generate();else if(t instanceof e)n=h.toLocalBufferType(new Uint8Array(t.buffer));else if(ArrayBuffer.isView(t)&&t.byteLength===gt)n=h.toLocalBufferType(t);else if(typeof t=="string")n=e.bytesFromString(t);else throw new o("Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).");super(n,ct)}get id(){return this.buffer}set id(t){this.buffer=t}toHexString(t=!0){return t?[h.toHex(this.buffer.subarray(0,4)),h.toHex(this.buffer.subarray(4,6)),h.toHex(this.buffer.subarray(6,8)),h.toHex(this.buffer.subarray(8,10)),h.toHex(this.buffer.subarray(10,16))].join("-"):h.toHex(this.buffer)}toString(t){return t==="hex"?h.toHex(this.id):t==="base64"?h.toBase64(this.id):this.toHexString()}toJSON(){return this.toHexString()}equals(t){if(!t)return!1;if(t instanceof e)return h.equals(t.id,this.id);try{return h.equals(new e(t).id,this.id)}catch{return!1}}toBinary(){return new _(this.id,_.SUBTYPE_UUID)}static generate(){let t=h.randomBytes(gt);return t[6]=t[6]&15|64,t[8]=t[8]&63|128,t}static isValid(t){return t?typeof t=="string"?e.isValidUUIDString(t):Lt(t)?t.byteLength===gt:t._bsontype==="Binary"&&t.sub_type===this.SUBTYPE_UUID&&t.buffer.byteLength===16:!1}static createFromHexString(t){let n=e.bytesFromString(t);return new e(n)}static createFromBase64(t){return new e(h.fromBase64(t))}static bytesFromString(t){if(!e.isValidUUIDString(t))throw new o("UUID string representation must be 32 hex digits or canonical hyphenated representation");return h.fromHex(t.replace(/-/g,""))}static isValidUUIDString(t){return Le.test(t)||Re.test(t)}inspect(t,n,s){return s??=j,`new UUID(${s(this.toHexString(),n)})`}},Y=class e extends D{get _bsontype(){return"Code"}constructor(t,n){super(),this.code=t.toString(),this.scope=n??null}toJSON(){return this.scope!=null?{code:this.code,scope:this.scope}:{code:this.code}}toExtendedJSON(){return this.scope?{$code:this.code,$scope:this.scope}:{$code:this.code}}static fromExtendedJSON(t){return new e(t.$code,t.$scope)}inspect(t,n,s){s??=j;let r=s(this.code,n),i=r.includes(` -`);this.scope!=null&&(r+=`,${i?` -`:" "}${s(this.scope,n)}`);let u=i&&this.scope===null;return`new Code(${i?` -`:""}${r}${u?` -`:""})`}};function Ht(e){return e!=null&&typeof e=="object"&&"$id"in e&&e.$id!=null&&"$ref"in e&&typeof e.$ref=="string"&&(!("$db"in e)||"$db"in e&&typeof e.$db=="string")}var P=class e extends D{get _bsontype(){return"DBRef"}constructor(t,n,s,r){super();let i=t.split(".");i.length===2&&(s=i.shift(),t=i.shift()),this.collection=t,this.oid=n,this.db=s,this.fields=r||{}}get namespace(){return this.collection}set namespace(t){this.collection=t}toJSON(){let t=Object.assign({$ref:this.collection,$id:this.oid},this.fields);return this.db!=null&&(t.$db=this.db),t}toExtendedJSON(t){t=t||{};let n={$ref:this.collection,$id:this.oid};return t.legacy||(this.db&&(n.$db=this.db),n=Object.assign(n,this.fields)),n}static fromExtendedJSON(t){let n=Object.assign({},t);return delete n.$ref,delete n.$id,delete n.$db,new e(t.$ref,t.$id,t.$db,n)}inspect(t,n,s){s??=j;let r=[s(this.namespace,n),s(this.oid,n),...this.db?[s(this.db,n)]:[],...Object.keys(this.fields).length>0?[s(this.fields,n)]:[]];return r[1]=s===j?`new ObjectId(${r[1]})`:r[1],`new DBRef(${r.join(", ")})`}},z;try{z=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,0,11,7,50,6,3,109,117,108,0,1,5,100,105,118,95,115,0,2,5,100,105,118,95,117,0,3,5,114,101,109,95,115,0,4,5,114,101,109,95,117,0,5,8,103,101,116,95,104,105,103,104,0,0,10,191,1,6,4,0,35,0,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,126,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,127,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,128,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,129,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,130,34,4,66,32,135,167,36,0,32,4,167,11])),{}).exports}catch{}var Bt=65536,De=1<<24,G=Bt*Bt,Jt=G*G,Ot=Jt/2,bt={},Et={},je=20,ze=/^(\+?0|(\+|-)?[1-9][0-9]*)$/,f=class e extends D{get _bsontype(){return"Long"}get __isLong__(){return!0}constructor(t=0,n,s){super(),typeof t=="bigint"?Object.assign(this,e.fromBigInt(t,!!n)):typeof t=="string"?Object.assign(this,e.fromString(t,!!n)):(this.low=t|0,this.high=n|0,this.unsigned=!!s)}static fromBits(t,n,s){return new e(t,n,s)}static fromInt(t,n){let s,r,i;return n?(t>>>=0,(i=0<=t&&t<256)&&(r=Et[t],r)?r:(s=e.fromBits(t,(t|0)<0?-1:0,!0),i&&(Et[t]=s),s)):(t|=0,(i=-128<=t&&t<128)&&(r=bt[t],r)?r:(s=e.fromBits(t,t<0?-1:0,!1),i&&(bt[t]=s),s))}static fromNumber(t,n){if(isNaN(t))return n?e.UZERO:e.ZERO;if(n){if(t<0)return e.UZERO;if(t>=Jt)return e.MAX_UNSIGNED_VALUE}else{if(t<=-Ot)return e.MIN_VALUE;if(t+1>=Ot)return e.MAX_VALUE}return t<0?e.fromNumber(-t,n).neg():e.fromBits(t%G|0,t/G|0,n)}static fromBigInt(t,n){return e.fromString(t.toString(),n)}static fromString(t,n,s){if(t.length===0)throw new o("empty string");if(t==="NaN"||t==="Infinity"||t==="+Infinity"||t==="-Infinity")return e.ZERO;if(typeof n=="number"?(s=n,n=!1):n=!!n,s=s||10,s<2||360)throw new o("interior hyphen");if(r===0)return e.fromString(t.substring(1),n,s).neg();let i=e.fromNumber(Math.pow(s,8)),u=e.ZERO;for(let a=0;a>>16,s=this.high&65535,r=this.low>>>16,i=this.low&65535,u=t.high>>>16,a=t.high&65535,I=t.low>>>16,S=t.low&65535,w=0,m=0,O=0,d=0;return d+=i+S,O+=d>>>16,d&=65535,O+=r+I,m+=O>>>16,O&=65535,m+=s+a,w+=m>>>16,m&=65535,w+=n+u,w&=65535,e.fromBits(O<<16|d,w<<16|m,this.unsigned)}and(t){return e.isLong(t)||(t=e.fromValue(t)),e.fromBits(this.low&t.low,this.high&t.high,this.unsigned)}compare(t){if(e.isLong(t)||(t=e.fromValue(t)),this.eq(t))return 0;let n=this.isNegative(),s=t.isNegative();return n&&!s?-1:!n&&s?1:this.unsigned?t.high>>>0>this.high>>>0||t.high===this.high&&t.low>>>0>this.low>>>0?-1:1:this.sub(t).isNegative()?-1:1}comp(t){return this.compare(t)}divide(t){if(e.isLong(t)||(t=e.fromValue(t)),t.isZero())throw new o("division by zero");if(z){if(!this.unsigned&&this.high===-2147483648&&t.low===-1&&t.high===-1)return this;let i=(this.unsigned?z.div_u:z.div_s)(this.low,this.high,t.low,t.high);return e.fromBits(i,z.get_high(),this.unsigned)}if(this.isZero())return this.unsigned?e.UZERO:e.ZERO;let n,s,r;if(this.unsigned){if(t.unsigned||(t=t.toUnsigned()),t.gt(this))return e.UZERO;if(t.gt(this.shru(1)))return e.UONE;r=e.UZERO}else{if(this.eq(e.MIN_VALUE))return t.eq(e.ONE)||t.eq(e.NEG_ONE)?e.MIN_VALUE:t.eq(e.MIN_VALUE)?e.ONE:(n=this.shr(1).div(t).shl(1),n.eq(e.ZERO)?t.isNegative()?e.ONE:e.NEG_ONE:(s=this.sub(t.mul(n)),r=n.add(s.div(t)),r));if(t.eq(e.MIN_VALUE))return this.unsigned?e.UZERO:e.ZERO;if(this.isNegative())return t.isNegative()?this.neg().div(t.neg()):this.neg().div(t).neg();if(t.isNegative())return this.div(t.neg()).neg();r=e.ZERO}for(s=this;s.gte(t);){n=Math.max(1,Math.floor(s.toNumber()/t.toNumber()));let i=Math.ceil(Math.log(n)/Math.LN2),u=i<=48?1:Math.pow(2,i-48),a=e.fromNumber(n),I=a.mul(t);for(;I.isNegative()||I.gt(s);)n-=u,a=e.fromNumber(n,this.unsigned),I=a.mul(t);a.isZero()&&(a=e.ONE),r=r.add(a),s=s.sub(I)}return r}div(t){return this.divide(t)}equals(t){return e.isLong(t)||(t=e.fromValue(t)),this.unsigned!==t.unsigned&&this.high>>>31===1&&t.high>>>31===1?!1:this.high===t.high&&this.low===t.low}eq(t){return this.equals(t)}getHighBits(){return this.high}getHighBitsUnsigned(){return this.high>>>0}getLowBits(){return this.low}getLowBitsUnsigned(){return this.low>>>0}getNumBitsAbs(){if(this.isNegative())return this.eq(e.MIN_VALUE)?64:this.neg().getNumBitsAbs();let t=this.high!==0?this.high:this.low,n;for(n=31;n>0&&!(t&1<0}gt(t){return this.greaterThan(t)}greaterThanOrEqual(t){return this.comp(t)>=0}gte(t){return this.greaterThanOrEqual(t)}ge(t){return this.greaterThanOrEqual(t)}isEven(){return(this.low&1)===0}isNegative(){return!this.unsigned&&this.high<0}isOdd(){return(this.low&1)===1}isPositive(){return this.unsigned||this.high>=0}isZero(){return this.high===0&&this.low===0}lessThan(t){return this.comp(t)<0}lt(t){return this.lessThan(t)}lessThanOrEqual(t){return this.comp(t)<=0}lte(t){return this.lessThanOrEqual(t)}modulo(t){if(e.isLong(t)||(t=e.fromValue(t)),z){let n=(this.unsigned?z.rem_u:z.rem_s)(this.low,this.high,t.low,t.high);return e.fromBits(n,z.get_high(),this.unsigned)}return this.sub(this.div(t).mul(t))}mod(t){return this.modulo(t)}rem(t){return this.modulo(t)}multiply(t){if(this.isZero())return e.ZERO;if(e.isLong(t)||(t=e.fromValue(t)),z){let x=z.mul(this.low,this.high,t.low,t.high);return e.fromBits(x,z.get_high(),this.unsigned)}if(t.isZero())return e.ZERO;if(this.eq(e.MIN_VALUE))return t.isOdd()?e.MIN_VALUE:e.ZERO;if(t.eq(e.MIN_VALUE))return this.isOdd()?e.MIN_VALUE:e.ZERO;if(this.isNegative())return t.isNegative()?this.neg().mul(t.neg()):this.neg().mul(t).neg();if(t.isNegative())return this.mul(t.neg()).neg();if(this.lt(e.TWO_PWR_24)&&t.lt(e.TWO_PWR_24))return e.fromNumber(this.toNumber()*t.toNumber(),this.unsigned);let n=this.high>>>16,s=this.high&65535,r=this.low>>>16,i=this.low&65535,u=t.high>>>16,a=t.high&65535,I=t.low>>>16,S=t.low&65535,w=0,m=0,O=0,d=0;return d+=i*S,O+=d>>>16,d&=65535,O+=r*S,m+=O>>>16,O&=65535,O+=i*I,m+=O>>>16,O&=65535,m+=s*S,w+=m>>>16,m&=65535,m+=r*I,w+=m>>>16,m&=65535,m+=i*a,w+=m>>>16,m&=65535,w+=n*S+s*I+r*a+i*u,w&=65535,e.fromBits(O<<16|d,w<<16|m,this.unsigned)}mul(t){return this.multiply(t)}negate(){return!this.unsigned&&this.eq(e.MIN_VALUE)?e.MIN_VALUE:this.not().add(e.ONE)}neg(){return this.negate()}not(){return e.fromBits(~this.low,~this.high,this.unsigned)}notEquals(t){return!this.equals(t)}neq(t){return this.notEquals(t)}ne(t){return this.notEquals(t)}or(t){return e.isLong(t)||(t=e.fromValue(t)),e.fromBits(this.low|t.low,this.high|t.high,this.unsigned)}shiftLeft(t){return e.isLong(t)&&(t=t.toInt()),(t&=63)===0?this:t<32?e.fromBits(this.low<>>32-t,this.unsigned):e.fromBits(0,this.low<>>t|this.high<<32-t,this.high>>t,this.unsigned):e.fromBits(this.high>>t-32,this.high>=0?0:-1,this.unsigned)}shr(t){return this.shiftRight(t)}shiftRightUnsigned(t){if(e.isLong(t)&&(t=t.toInt()),t&=63,t===0)return this;{let n=this.high;if(t<32){let s=this.low;return e.fromBits(s>>>t|n<<32-t,n>>>t,this.unsigned)}else return t===32?e.fromBits(n,0,this.unsigned):e.fromBits(n>>>t-32,0,this.unsigned)}}shr_u(t){return this.shiftRightUnsigned(t)}shru(t){return this.shiftRightUnsigned(t)}subtract(t){return e.isLong(t)||(t=e.fromValue(t)),this.add(t.neg())}sub(t){return this.subtract(t)}toInt(){return this.unsigned?this.low>>>0:this.low}toNumber(){return this.unsigned?(this.high>>>0)*G+(this.low>>>0):this.high*G+(this.low>>>0)}toBigInt(){return BigInt(this.toString())}toBytes(t){return t?this.toBytesLE():this.toBytesBE()}toBytesLE(){let t=this.high,n=this.low;return[n&255,n>>>8&255,n>>>16&255,n>>>24,t&255,t>>>8&255,t>>>16&255,t>>>24]}toBytesBE(){let t=this.high,n=this.low;return[t>>>24,t>>>16&255,t>>>8&255,t&255,n>>>24,n>>>16&255,n>>>8&255,n&255]}toSigned(){return this.unsigned?e.fromBits(this.low,this.high,!1):this}toString(t){if(t=t||10,t<2||36>>0).toString(t);if(s=i,s.isZero())return a+r;for(;a.length<6;)a="0"+a;r=""+a+r}}toUnsigned(){return this.unsigned?this:e.fromBits(this.low,this.high,!0)}xor(t){return e.isLong(t)||(t=e.fromValue(t)),e.fromBits(this.low^t.low,this.high^t.high,this.unsigned)}eqz(){return this.isZero()}le(t){return this.lessThanOrEqual(t)}toExtendedJSON(t){return t&&t.relaxed?this.toNumber():{$numberLong:this.toString()}}static fromExtendedJSON(t,n){let{useBigInt64:s=!1,relaxed:r=!0}={...n};if(t.$numberLong.length>je)throw new o("$numberLong string is too long");if(!ze.test(t.$numberLong))throw new o(`$numberLong string "${t.$numberLong}" is in an invalid format`);if(s){let u=BigInt(t.$numberLong);return BigInt.asIntN(64,u)}let i=e.fromString(t.$numberLong);return r?i.toNumber():i}inspect(t,n,s){s??=j;let r=s(this.toString(),n),i=this.unsigned?`, ${s(this.unsigned,n)}`:"";return`new Long(${r}${i})`}};f.TWO_PWR_24=f.fromInt(De);f.MAX_UNSIGNED_VALUE=f.fromBits(-1,-1,!0);f.ZERO=f.fromInt(0);f.UZERO=f.fromInt(0,!0);f.ONE=f.fromInt(1);f.UONE=f.fromInt(1,!0);f.NEG_ONE=f.fromInt(-1);f.MAX_VALUE=f.fromBits(-1,2147483647,!1);f.MIN_VALUE=f.fromBits(0,-2147483648,!1);var Fe=/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/,Me=/^(\+|-)?(Infinity|inf)$/i,xe=/^(\+|-)?NaN$/i,K=6111,nt=-6176,Tt=6176,It=34,ut=h.fromNumberArray([124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse()),dt=h.fromNumberArray([248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse()),$t=h.fromNumberArray([120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse()),He=/^([-+])?(\d+)?$/,Je=31,At=16383,Ce=30,Pe=31;function _t(e){return!isNaN(parseInt(e,10))}function Ve(e){let t=f.fromNumber(1e9),n=f.fromNumber(0);if(!e.parts[0]&&!e.parts[1]&&!e.parts[2]&&!e.parts[3])return{quotient:e,rem:n};for(let s=0;s<=3;s++)n=n.shiftLeft(32),n=n.add(new f(e.parts[s],0)),e.parts[s]=n.div(t).low,n=n.modulo(t);return{quotient:e,rem:n}}function We(e,t){if(!e&&!t)return{high:f.fromNumber(0),low:f.fromNumber(0)};let n=e.shiftRightUnsigned(32),s=new f(e.getLowBits(),0),r=t.shiftRightUnsigned(32),i=new f(t.getLowBits(),0),u=n.multiply(r),a=n.multiply(i),I=s.multiply(r),S=s.multiply(i);return u=u.add(a.shiftRightUnsigned(32)),a=new f(a.getLowBits(),0).add(I).add(S.shiftRightUnsigned(32)),u=u.add(a.shiftRightUnsigned(32)),S=a.shiftLeft(32).add(new f(S.getLowBits(),0)),{high:u,low:S}}function Ye(e,t){let n=e.high>>>0,s=t.high>>>0;if(n>>0,i=t.low>>>0;if(r=7e3)throw new o(""+t+" not a valid Decimal128 string");let U=t.match(Fe),ft=t.match(Me),N=t.match(xe);if(!U&&!ft&&!N||t.length===0)throw new o(""+t+" not a valid Decimal128 string");if(U){let c=U[2],l=U[4],p=U[5],B=U[6];l&&B===void 0&&M(t,"missing exponent power"),l&&c===void 0&&M(t,"missing exponent base"),l===void 0&&(p||B)&&M(t,"missing e before exponent")}if((t[g]==="+"||t[g]==="-")&&(r=!0,s=t[g++]==="-"),!_t(t[g])&&t[g]!=="."){if(t[g]==="i"||t[g]==="I")return new e(s?dt:$t);if(t[g]==="N")return new e(ut)}for(;_t(t[g])||t[g]===".";){if(t[g]==="."){i&&M(t,"contains multiple periods"),i=!0,g=g+1;continue}d$+16384?$=nt:$=$-w;$>K;){if(E=E+1,E>=It){if(a===0){$=K;break}M(t,"overflow")}$=$-1}if(n.allowRounding){for(;$=5&&(p=1,l===5)){p=O[E]%2===1?1:0;for(let B=m+E+2;B=0&&++O[B]>9;B--)if(O[B]=0,B===0)if($>8&255,A[g++]=b.low.low>>16&255,A[g++]=b.low.low>>24&255,A[g++]=b.low.high&255,A[g++]=b.low.high>>8&255,A[g++]=b.low.high>>16&255,A[g++]=b.low.high>>24&255,A[g++]=b.high.low&255,A[g++]=b.high.low>>8&255,A[g++]=b.high.low>>16&255,A[g++]=b.high.low>>24&255,A[g++]=b.high.high&255,A[g++]=b.high.high>>8&255,A[g++]=b.high.high>>16&255,A[g++]=b.high.high>>24&255,new e(A)}toString(){let t,n=0,s=new Array(36);for(let g=0;g>26&Je;if(L>>3===3){if(L===Ce)return w.join("")+"Infinity";if(L===Pe)return"NaN";t=E>>15&At,u=8+(E>>14&1)}else u=E>>14&7,t=E>>17&At;let T=t-Tt;if(a.parts[0]=(E&16383)+((u&15)<<14),a.parts[1]=x,a.parts[2]=d,a.parts[3]=O,a.parts[0]===0&&a.parts[1]===0&&a.parts[2]===0&&a.parts[3]===0)i=!0;else for(S=3;S>=0;S--){let g=0,U=Ve(a);if(a=U.quotient,g=U.rem.low,!!g)for(I=8;I>=0;I--)s[S*9+I]=g%10,g=Math.floor(g/10)}if(i)n=1,s[r]=0;else for(n=36;!s[r];)n=n-1,r=r+1;let F=n-1+T;if(F>=34||F<=-7||T>0){if(n>34)return w.push("0"),T>0?w.push(`E+${T}`):T<0&&w.push(`E${T}`),w.join("");w.push(`${s[r++]}`),n=n-1,n&&w.push(".");for(let g=0;g0?w.push(`+${F}`):w.push(`${F}`)}else if(T>=0)for(let g=0;g0)for(let U=0;U>8&255,s[9]=n>>16&255,s}toString(t){return t==="base64"?h.toBase64(this.id):t==="hex"?this.toHexString():this.toHexString()}toJSON(){return this.toHexString()}static is(t){return t!=null&&typeof t=="object"&&"_bsontype"in t&&t._bsontype==="ObjectId"}equals(t){if(t==null)return!1;if(e.is(t))return this[H][11]===t[H][11]&&h.equals(this[H],t[H]);if(typeof t=="string")return t.toLowerCase()===this.toHexString();if(typeof t=="object"&&typeof t.toHexString=="function"){let n=t.toHexString(),s=this.toHexString();return typeof n=="string"&&n.toLowerCase()===s}return!1}getTimestamp(){let t=new Date,n=Q.fromUint8Array(this.id).getUint32(0,!1);return t.setTime(Math.floor(n)*1e3),t}static createPk(){return new e}static createFromTime(t){let n=h.fromNumberArray([0,0,0,0,0,0,0,0,0,0,0,0]);return Q.fromUint8Array(n).setUint32(0,t,!1),new e(n)}static createFromHexString(t){if(t?.length!==24)throw new o("hex string must be 24 characters");return new e(h.fromHex(t))}static createFromBase64(t){if(t?.length!==16)throw new o("base64 string must be 16 characters");return new e(h.fromBase64(t))}static isValid(t){if(t==null)return!1;try{return new e(t),!0}catch{return!1}}toExtendedJSON(){return this.toHexString?{$oid:this.toHexString()}:{$oid:this.toString("hex")}}static fromExtendedJSON(t){return new e(t.$oid)}inspect(t,n,s){return s??=j,`new ObjectId(${s(this.toHexString(),n)})`}};k.index=Math.floor(Math.random()*16777215);function qe(e){return e.split("").sort().join("")}var q=class e extends D{get _bsontype(){return"BSONRegExp"}constructor(t,n){if(super(),this.pattern=t,this.options=qe(n??""),this.pattern.indexOf("\0")!==-1)throw new o(`BSON Regex patterns cannot contain null bytes, found: ${JSON.stringify(this.pattern)}`);if(this.options.indexOf("\0")!==-1)throw new o(`BSON Regex options cannot contain null bytes, found: ${JSON.stringify(this.options)}`);for(let s=0;sa);s??=j;let i=r(s(this.pattern),"regexp"),u=r(s(this.options),"regexp");return`new BSONRegExp(${i}, ${u})`}},ot=class e extends D{get _bsontype(){return"BSONSymbol"}constructor(t){super(),this.value=t}valueOf(){return this.value}toString(){return this.value}toJSON(){return this.value}toExtendedJSON(){return{$symbol:this.value}}static fromExtendedJSON(t){return new e(t.$symbol)}inspect(t,n,s){return s??=j,`new BSONSymbol(${s(this.value,n)})`}},Ze=f,et=class e extends Ze{get _bsontype(){return"Timestamp"}constructor(t){if(t==null)super(0,0,!0);else if(typeof t=="bigint")super(t,!0);else if(f.isLong(t))super(t.low,t.high,!0);else if(typeof t=="object"&&"t"in t&&"i"in t){if(typeof t.t!="number"&&(typeof t.t!="object"||t.t._bsontype!=="Int32"))throw new o("Timestamp constructed from { t, i } must provide t as a number");if(typeof t.i!="number"&&(typeof t.i!="object"||t.i._bsontype!=="Int32"))throw new o("Timestamp constructed from { t, i } must provide i as a number");let n=Number(t.t),s=Number(t.i);if(n<0||Number.isNaN(n))throw new o("Timestamp constructed from { t, i } must provide a positive t");if(s<0||Number.isNaN(s))throw new o("Timestamp constructed from { t, i } must provide a positive i");if(n>4294967295)throw new o("Timestamp constructed from { t, i } must provide t equal or less than uint32 max");if(s>4294967295)throw new o("Timestamp constructed from { t, i } must provide i equal or less than uint32 max");super(s,n,!0)}else throw new o("A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }")}toJSON(){return{$timestamp:this.toString()}}static fromInt(t){return new e(f.fromInt(t,!0))}static fromNumber(t){return new e(f.fromNumber(t,!0))}static fromBits(t,n){return new e({i:t,t:n})}static fromString(t,n){return new e(f.fromString(t,!0,n))}toExtendedJSON(){return{$timestamp:{t:this.high>>>0,i:this.low>>>0}}}static fromExtendedJSON(t){let n=f.isLong(t.$timestamp.i)?t.$timestamp.i.getLowBitsUnsigned():t.$timestamp.i,s=f.isLong(t.$timestamp.t)?t.$timestamp.t.getLowBitsUnsigned():t.$timestamp.t;return new e({t:s,i:n})}inspect(t,n,s){s??=j;let r=s(this.high>>>0,n),i=s(this.low>>>0,n);return`new Timestamp({ t: ${r}, i: ${i} })`}};et.MAX_VALUE=f.MAX_UNSIGNED_VALUE;var Ke=f.fromNumber(Gt),Ge=f.fromNumber(Xt);function Xe(e,t,n){t=t??{};let s=t&&t.index?t.index:0,r=e[s]|e[s+1]<<8|e[s+2]<<16|e[s+3]<<24;if(r<5)throw new o(`bson size must be >= 5, is ${r}`);if(t.allowObjectSmallerThanBufferSize&&e.length= bson size ${r}`);if(!t.allowObjectSmallerThanBufferSize&&e.length!==r)throw new o(`buffer length ${e.length} must === bson size ${r}`);if(r+s>e.byteLength)throw new o(`(bson size ${r} + options.index ${s} must be <= buffer length ${e.byteLength})`);if(e[s+r-1]!==0)throw new o("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");return lt(e,s,t,n)}var Qe=/^\$ref$|^\$id$|^\$db$/;function lt(e,t,n,s=!1){let r=n.fieldsAsRaw==null?null:n.fieldsAsRaw,i=n.raw==null?!1:n.raw,u=typeof n.bsonRegExp=="boolean"?n.bsonRegExp:!1,a=n.promoteBuffers??!1,I=n.promoteLongs??!0,S=n.promoteValues??!0,w=n.useBigInt64??!1;if(w&&!S)throw new o("Must either request bigint or Long for int64 deserialization");if(w&&!I)throw new o("Must either request bigint or Long for int64 deserialization");let m=n.validation==null?{utf8:!0}:n.validation,O=!0,d,x=new Set,E=m.utf8;if(typeof E=="boolean")d=E;else{O=!1;let N=Object.keys(E).map(function(y){return E[y]});if(N.length===0)throw new o("UTF-8 validation setting cannot be empty");if(typeof N[0]!="boolean")throw new o("Invalid UTF-8 validation option, must specify boolean values");if(d=N[0],!N.every(y=>y===d))throw new o("Invalid UTF-8 validation option - keys must be all true or all false")}if(!O)for(let N of Object.keys(E))x.add(N);let $=t;if(e.length<5)throw new o("corrupt bson message < 5 bytes long");let L=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(L<5||L>e.length)throw new o("corrupt bson message");let T=s?[]:{},F=0,g=!1,U=s?!1:null,ft=new DataView(e.buffer,e.byteOffset,e.byteLength);for(;!g;){let N=e[t++];if(N===0)break;let y=t;for(;e[y]!==0&&y=e.byteLength)throw new o("Bad BSON Document: illegal CString");let b=s?F++:h.toUTF8(e,t,y,!1),A=!0;O||x.has(b)?A=d:A=!d,U!==!1&&b[0]==="$"&&(U=Qe.test(b));let c;if(t=y+1,N===Qt){let l=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(l<=0||l>e.length-t||e[t+l-1]!==0)throw new o("bad string length in bson");c=h.toUTF8(e,t,t+l-1,A),t=t+l}else if(N===se){let l=h.allocate(12);l.set(e.subarray(t,t+12)),c=new k(l),t=t+12}else if(N===St&&S===!1)c=new tt(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24);else if(N===St)c=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;else if(N===wt&&S===!1)c=new v(ft.getFloat64(t,!0)),t=t+8;else if(N===wt)c=ft.getFloat64(t,!0),t=t+8;else if(N===ie){let l=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,p=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;c=new Date(new f(l,p).toNumber())}else if(N===re){if(e[t]!==0&&e[t]!==1)throw new o("illegal boolean type value");c=e[t++]===1}else if(N===vt){let l=t,p=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24;if(p<=0||p>e.length-t)throw new o("bad embedded document length in bson");if(i)c=e.slice(t,t+p);else{let B=n;O||(B={...n,validation:{utf8:A}}),c=lt(e,l,B,!1)}t=t+p}else if(N===te){let l=t,p=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24,B=n,R=t+p;if(r&&r[b]&&(B={...n,raw:!0}),O||(B={...B,validation:{utf8:A}}),c=lt(e,l,B,!0),t=t+p,e[t-1]!==0)throw new o("invalid array terminator byte");if(t!==R)throw new o("corrupted array bson")}else if(N===ne)c=void 0;else if(N===oe)c=null;else if(N===ge){let l=Q.fromUint8Array(e.subarray(t,t+8)),p=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,B=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,R=new f(p,B);w?c=l.getBigInt64(0,!0):I&&S===!0?c=R.lessThanOrEqual(Ke)&&R.greaterThanOrEqual(Ge)?R.toNumber():R:c=R}else if(N===ue){let l=h.allocate(16);l.set(e.subarray(t,t+16),0),t=t+16,c=new st(l)}else if(N===ee){let l=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,p=l,B=e[t++];if(l<0)throw new o("Negative binary type element size found");if(l>e.byteLength)throw new o("Binary type size larger than document size");if(e.slice!=null){if(B===_.SUBTYPE_BYTE_ARRAY){if(l=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,l<0)throw new o("Negative binary type element size found for subtype 0x02");if(l>p-4)throw new o("Binary type with subtype 0x02 contains too long binary size");if(lp-4)throw new o("Binary type with subtype 0x02 contains too long binary size");if(l=e.length)throw new o("Bad BSON Document: illegal CString");let l=h.toUTF8(e,t,y,!1);for(t=y+1,y=t;e[y]!==0&&y=e.length)throw new o("Bad BSON Document: illegal CString");let p=h.toUTF8(e,t,y,!1);t=y+1;let B=new Array(p.length);for(y=0;y=e.length)throw new o("Bad BSON Document: illegal CString");let l=h.toUTF8(e,t,y,!1);for(t=y+1,y=t;e[y]!==0&&y=e.length)throw new o("Bad BSON Document: illegal CString");let p=h.toUTF8(e,t,y,!1);t=y+1,c=new q(l,p)}else if(N===ce){let l=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(l<=0||l>e.length-t||e[t+l-1]!==0)throw new o("bad string length in bson");let p=h.toUTF8(e,t,t+l-1,A);c=S?p:new ot(p),t=t+l}else if(N===ae){let l=e[t++]+e[t++]*256+e[t++]*65536+e[t++]*16777216,p=e[t++]+e[t++]*256+e[t++]*65536+e[t++]*(1<<24);c=new et({i:l,t:p})}else if(N===ye)c=new it;else if(N===me)c=new rt;else if(N===le){let l=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(l<=0||l>e.length-t||e[t+l-1]!==0)throw new o("bad string length in bson");let p=h.toUTF8(e,t,t+l-1,A);c=new Y(p),t=t+l}else if(N===he){let l=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(l<4+4+4+1)throw new o("code_w_scope total size shorter minimum expected length");let p=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(p<=0||p>e.length-t||e[t+p-1]!==0)throw new o("bad string length in bson");let B=h.toUTF8(e,t,t+p-1,A);t=t+p;let R=t,at=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24,Yt=lt(e,R,n,!1);if(t=t+at,l<4+4+at+p)throw new o("code_w_scope total size is too short, truncating scope");if(l>4+4+at+p)throw new o("code_w_scope total size is too long, clips outer document");c=new Y(B,Yt)}else if(N===fe){let l=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(l<=0||l>e.length-t||e[t+l-1]!==0)throw new o("bad string length in bson");if(m!=null&&m.utf8&&!Mt(e,t,t+l-1))throw new o("Invalid UTF-8 string in BSON document");let p=h.toUTF8(e,t,t+l-1,!1);t=t+l;let B=h.allocate(12);B.set(e.subarray(t,t+12),0);let R=new k(B);t=t+12,c=new P(p,R)}else throw new o(`Detected unknown BSON type ${N.toString(16)} for fieldname "${b}"`);b==="__proto__"?Object.defineProperty(T,b,{value:c,writable:!0,enumerable:!0,configurable:!0}):T[b]=c}if(L!==t-$)throw s?new o("corrupt array bson"):new o("corrupt object bson");if(!U)return T;if(Ht(T)){let N=Object.assign({},T);return delete N.$ref,delete N.$id,delete N.$db,new P(T.$ref,T.$id,T.$db,N)}return T}var Ct=new DataView(new ArrayBuffer(8),0,8),hn=new Uint8Array(Ct.buffer,0,4),an=new Uint8Array(Ct.buffer,0,8);function ve(e){return e!=null&&typeof e=="object"&&"_bsontype"in e&&typeof e._bsontype=="string"}var tn={$oid:k,$binary:_,$uuid:_,$symbol:ot,$numberInt:tt,$numberDecimal:st,$numberDouble:v,$numberLong:f,$minKey:it,$maxKey:rt,$regex:q,$regularExpression:q,$timestamp:et};function Pt(e,t={}){if(typeof e=="number"){let s=e<=Dt&&e>=jt,r=e<=zt&&e>=Ft;if(t.relaxed||t.legacy)return e;if(Number.isInteger(e)&&!Object.is(e,-0)){if(s)return new tt(e);if(r)return t.useBigInt64?BigInt(e):f.fromNumber(e)}return new v(e)}if(e==null||typeof e!="object")return e;if(e.$undefined)return null;let n=Object.keys(e).filter(s=>s.startsWith("$")&&e[s]!=null);for(let s=0;su.startsWith("$")),i=!0;if(r.forEach(u=>{["$ref","$id","$db"].indexOf(u)===-1&&(i=!1)}),i)return P.fromExtendedJSON(s)}return e}function en(e,t){return e.map((n,s)=>{t.seenObjects.push({propertyName:`index ${s}`,obj:null});try{return J(n,t)}finally{t.seenObjects.pop()}})}function Ut(e){let t=e.toISOString();return e.getUTCMilliseconds()!==0?t:t.slice(0,-5)+"Z"}function J(e,t){if(e instanceof Map||Rt(e)){let n=Object.create(null);for(let[s,r]of e){if(typeof s!="string")throw new o("Can only serialize maps with string keys");n[s]=r}return J(n,t)}if((typeof e=="object"||typeof e=="function")&&e!==null){let n=t.seenObjects.findIndex(s=>s.obj===e);if(n!==-1){let s=t.seenObjects.map(w=>w.propertyName),r=s.slice(0,n).map(w=>`${w} -> `).join(""),i=s[n],u=" -> "+s.slice(n+1,s.length-1).map(w=>`${w} -> `).join(""),a=s[s.length-1],I=" ".repeat(r.length+i.length/2),S="-".repeat(u.length+(i.length+a.length)/2-1);throw new o(`Converting circular structure to EJSON: - ${r}${i}${u}${a} - ${I}\\${S}/`)}t.seenObjects[t.seenObjects.length-1].obj=e}if(Array.isArray(e))return en(e,t);if(e===void 0)return null;if(e instanceof Date||Zt(e)){let n=e.getTime(),s=n>-1&&n<2534023188e5;return t.legacy?t.relaxed&&s?{$date:e.getTime()}:{$date:Ut(e)}:t.relaxed&&s?{$date:Ut(e)}:{$date:{$numberLong:e.getTime().toString()}}}if(typeof e=="number"&&(!t.relaxed||!isFinite(e))){if(Number.isInteger(e)&&!Object.is(e,-0)){if(e>=jt&&e<=Dt)return{$numberInt:e.toString()};if(e>=Ft&&e<=zt)return{$numberLong:e.toString()}}return{$numberDouble:Object.is(e,-0)?"-0.0":e.toString()}}if(typeof e=="bigint")return t.relaxed?Number(BigInt.asIntN(64,e)):{$numberLong:BigInt.asIntN(64,e).toString()};if(e instanceof RegExp||qt(e)){let n=e.flags;if(n===void 0){let r=e.toString().match(/[gimuy]*$/);r&&(n=r[0])}return new q(e.source,n).toExtendedJSON(t)}return e!=null&&typeof e=="object"?sn(e,t):e}var nn={Binary:e=>new _(e.value(),e.sub_type),Code:e=>new Y(e.code,e.scope),DBRef:e=>new P(e.collection||e.namespace,e.oid,e.db,e.fields),Decimal128:e=>new st(e.bytes),Double:e=>new v(e.value),Int32:e=>new tt(e.value),Long:e=>f.fromBits(e.low!=null?e.low:e.low_,e.low!=null?e.high:e.high_,e.low!=null?e.unsigned:e.unsigned_),MaxKey:()=>new rt,MinKey:()=>new it,ObjectId:e=>new k(e),BSONRegExp:e=>new q(e.pattern,e.options),BSONSymbol:e=>new ot(e.value),Timestamp:e=>et.fromBits(e.low,e.high)};function sn(e,t){if(e==null||typeof e!="object")throw new o("not an object instance");let n=e._bsontype;if(typeof n>"u"){let s={};for(let r of Object.keys(e)){t.seenObjects.push({propertyName:r,obj:null});try{let i=J(e[r],t);r==="__proto__"?Object.defineProperty(s,r,{value:i,writable:!0,enumerable:!0,configurable:!0}):s[r]=i}finally{t.seenObjects.pop()}}return s}else{if(e!=null&&typeof e=="object"&&typeof e._bsontype=="string"&&e[Symbol.for("@@mdb.bson.version")]!==mt)throw new yt;if(ve(e)){let s=e;if(typeof s.toExtendedJSON!="function"){let r=nn[e._bsontype];if(!r)throw new o("Unrecognized or invalid _bsontype: "+e._bsontype);s=r(s)}return n==="Code"&&s.scope?s=new Y(s.code,J(s.scope,t)):n==="DBRef"&&s.oid&&(s=new P(J(s.collection,t),J(s.oid,t),J(s.db,t),J(s.fields,t))),s.toExtendedJSON(t)}else throw new o("_bsontype must be a string, but was: "+typeof n)}}function Vt(e,t){let n={useBigInt64:t?.useBigInt64??!1,relaxed:t?.relaxed??!0,legacy:t?.legacy??!1};return JSON.parse(e,(s,r)=>{if(s.indexOf("\0")!==-1)throw new o(`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(s)}`);return Pt(r,n)})}function Wt(e,t,n,s){n!=null&&typeof n=="object"&&(s=n,n=0),t!=null&&typeof t=="object"&&!Array.isArray(t)&&(s=t,t=void 0,n=0);let r=Object.assign({relaxed:!0,legacy:!1},s,{seenObjects:[{propertyName:"(root)",obj:null}]}),i=J(e,r);return JSON.stringify(i,t,n)}function rn(e,t){return t=t||{},JSON.parse(Wt(e,t))}function on(e,t){return t=t||{},Vt(JSON.stringify(e),t)}var Z=Object.create(null);Z.parse=Vt;Z.stringify=Wt;Z.serialize=rn;Z.deserialize=on;Object.freeze(Z);var fn=1024*1024*17,gn=h.allocate(fn);function ln(e,t={}){return Xe(h.toLocalBufferType(e),t)}var mn=Z.deserialize;export{ln as deserialize,mn as toJson}; +const bson=(() => { + var __getOwnPropNames = Object.getOwnPropertyNames; + var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a, b) => (typeof require !== "undefined" ? require : a)[b] + }) : x)(function(x) { + if (typeof require !== "undefined") + return require.apply(this, arguments); + throw Error('Dynamic require of "' + x + '" is not supported'); + }); + var __commonJS = (cb, mod) => function __require2() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + }; + + // ../../node_modules/bson/lib/bson.cjs + var require_bson = __commonJS({ + "../../node_modules/bson/lib/bson.cjs"(exports) { + "use strict"; + function isAnyArrayBuffer(value) { + return ["[object ArrayBuffer]", "[object SharedArrayBuffer]"].includes(Object.prototype.toString.call(value)); + } + function isUint8Array(value) { + return Object.prototype.toString.call(value) === "[object Uint8Array]"; + } + function isRegExp(d) { + return Object.prototype.toString.call(d) === "[object RegExp]"; + } + function isMap(d) { + return Object.prototype.toString.call(d) === "[object Map]"; + } + function isDate(d) { + return Object.prototype.toString.call(d) === "[object Date]"; + } + function defaultInspect(x, _options) { + return JSON.stringify(x, (k, v) => { + if (typeof v === "bigint") { + return { $numberLong: `${v}` }; + } else if (isMap(v)) { + return Object.fromEntries(v); + } + return v; + }); + } + function getStylizeFunction(options) { + const stylizeExists = options != null && typeof options === "object" && "stylize" in options && typeof options.stylize === "function"; + if (stylizeExists) { + return options.stylize; + } + } + var BSON_MAJOR_VERSION = 6; + var BSON_INT32_MAX = 2147483647; + var BSON_INT32_MIN = -2147483648; + var BSON_INT64_MAX = Math.pow(2, 63) - 1; + var BSON_INT64_MIN = -Math.pow(2, 63); + var JS_INT_MAX = Math.pow(2, 53); + var JS_INT_MIN = -Math.pow(2, 53); + var BSON_DATA_NUMBER = 1; + var BSON_DATA_STRING = 2; + var BSON_DATA_OBJECT = 3; + var BSON_DATA_ARRAY = 4; + var BSON_DATA_BINARY = 5; + var BSON_DATA_UNDEFINED = 6; + var BSON_DATA_OID = 7; + var BSON_DATA_BOOLEAN = 8; + var BSON_DATA_DATE = 9; + var BSON_DATA_NULL = 10; + var BSON_DATA_REGEXP = 11; + var BSON_DATA_DBPOINTER = 12; + var BSON_DATA_CODE = 13; + var BSON_DATA_SYMBOL = 14; + var BSON_DATA_CODE_W_SCOPE = 15; + var BSON_DATA_INT = 16; + var BSON_DATA_TIMESTAMP = 17; + var BSON_DATA_LONG = 18; + var BSON_DATA_DECIMAL128 = 19; + var BSON_DATA_MIN_KEY = 255; + var BSON_DATA_MAX_KEY = 127; + var BSON_BINARY_SUBTYPE_DEFAULT = 0; + var BSON_BINARY_SUBTYPE_UUID_NEW = 4; + var BSONType = Object.freeze({ + double: 1, + string: 2, + object: 3, + array: 4, + binData: 5, + undefined: 6, + objectId: 7, + bool: 8, + date: 9, + null: 10, + regex: 11, + dbPointer: 12, + javascript: 13, + symbol: 14, + javascriptWithScope: 15, + int: 16, + timestamp: 17, + long: 18, + decimal: 19, + minKey: -1, + maxKey: 127 + }); + var BSONError = class extends Error { + get bsonError() { + return true; + } + get name() { + return "BSONError"; + } + constructor(message, options) { + super(message, options); + } + static isBSONError(value) { + return value != null && typeof value === "object" && "bsonError" in value && value.bsonError === true && "name" in value && "message" in value && "stack" in value; + } + }; + var BSONVersionError = class extends BSONError { + get name() { + return "BSONVersionError"; + } + constructor() { + super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.x.x`); + } + }; + var BSONRuntimeError = class extends BSONError { + get name() { + return "BSONRuntimeError"; + } + constructor(message) { + super(message); + } + }; + var FIRST_BIT = 128; + var FIRST_TWO_BITS = 192; + var FIRST_THREE_BITS = 224; + var FIRST_FOUR_BITS = 240; + var FIRST_FIVE_BITS = 248; + var TWO_BIT_CHAR = 192; + var THREE_BIT_CHAR = 224; + var FOUR_BIT_CHAR = 240; + var CONTINUING_CHAR = 128; + function validateUtf8(bytes, start, end) { + let continuation = 0; + for (let i = start; i < end; i += 1) { + const byte = bytes[i]; + if (continuation) { + if ((byte & FIRST_TWO_BITS) !== CONTINUING_CHAR) { + return false; + } + continuation -= 1; + } else if (byte & FIRST_BIT) { + if ((byte & FIRST_THREE_BITS) === TWO_BIT_CHAR) { + continuation = 1; + } else if ((byte & FIRST_FOUR_BITS) === THREE_BIT_CHAR) { + continuation = 2; + } else if ((byte & FIRST_FIVE_BITS) === FOUR_BIT_CHAR) { + continuation = 3; + } else { + return false; + } + } + } + return !continuation; + } + function tryLatin(uint8array, start, end) { + if (uint8array.length === 0) { + return ""; + } + const stringByteLength = end - start; + if (stringByteLength === 0) { + return ""; + } + if (stringByteLength > 20) { + return null; + } + if (stringByteLength === 1 && uint8array[start] < 128) { + return String.fromCharCode(uint8array[start]); + } + if (stringByteLength === 2 && uint8array[start] < 128 && uint8array[start + 1] < 128) { + return String.fromCharCode(uint8array[start]) + String.fromCharCode(uint8array[start + 1]); + } + if (stringByteLength === 3 && uint8array[start] < 128 && uint8array[start + 1] < 128 && uint8array[start + 2] < 128) { + return String.fromCharCode(uint8array[start]) + String.fromCharCode(uint8array[start + 1]) + String.fromCharCode(uint8array[start + 2]); + } + const latinBytes = []; + for (let i = start; i < end; i++) { + const byte = uint8array[i]; + if (byte > 127) { + return null; + } + latinBytes.push(byte); + } + return String.fromCharCode(...latinBytes); + } + function nodejsMathRandomBytes(byteLength) { + return nodeJsByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256))); + } + var nodejsRandomBytes = (() => { + try { + return __require("crypto").randomBytes; + } catch { + return nodejsMathRandomBytes; + } + })(); + var nodeJsByteUtils = { + toLocalBufferType(potentialBuffer) { + if (Buffer.isBuffer(potentialBuffer)) { + return potentialBuffer; + } + if (ArrayBuffer.isView(potentialBuffer)) { + return Buffer.from(potentialBuffer.buffer, potentialBuffer.byteOffset, potentialBuffer.byteLength); + } + const stringTag = potentialBuffer?.[Symbol.toStringTag] ?? Object.prototype.toString.call(potentialBuffer); + if (stringTag === "ArrayBuffer" || stringTag === "SharedArrayBuffer" || stringTag === "[object ArrayBuffer]" || stringTag === "[object SharedArrayBuffer]") { + return Buffer.from(potentialBuffer); + } + throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`); + }, + allocate(size) { + return Buffer.alloc(size); + }, + equals(a, b) { + return nodeJsByteUtils.toLocalBufferType(a).equals(b); + }, + fromNumberArray(array) { + return Buffer.from(array); + }, + fromBase64(base64) { + return Buffer.from(base64, "base64"); + }, + toBase64(buffer2) { + return nodeJsByteUtils.toLocalBufferType(buffer2).toString("base64"); + }, + fromISO88591(codePoints) { + return Buffer.from(codePoints, "binary"); + }, + toISO88591(buffer2) { + return nodeJsByteUtils.toLocalBufferType(buffer2).toString("binary"); + }, + fromHex(hex) { + return Buffer.from(hex, "hex"); + }, + toHex(buffer2) { + return nodeJsByteUtils.toLocalBufferType(buffer2).toString("hex"); + }, + fromUTF8(text) { + return Buffer.from(text, "utf8"); + }, + toUTF8(buffer2, start, end, fatal) { + const basicLatin = end - start <= 20 ? tryLatin(buffer2, start, end) : null; + if (basicLatin != null) { + return basicLatin; + } + const string = nodeJsByteUtils.toLocalBufferType(buffer2).toString("utf8", start, end); + if (fatal) { + for (let i = 0; i < string.length; i++) { + if (string.charCodeAt(i) === 65533) { + if (!validateUtf8(buffer2, start, end)) { + throw new BSONError("Invalid UTF-8 string in BSON document"); + } + break; + } + } + } + return string; + }, + utf8ByteLength(input) { + return Buffer.byteLength(input, "utf8"); + }, + encodeUTF8Into(buffer2, source, byteOffset) { + return nodeJsByteUtils.toLocalBufferType(buffer2).write(source, byteOffset, void 0, "utf8"); + }, + randomBytes: nodejsRandomBytes + }; + function isReactNative() { + const { navigator } = globalThis; + return typeof navigator === "object" && navigator.product === "ReactNative"; + } + function webMathRandomBytes(byteLength) { + if (byteLength < 0) { + throw new RangeError(`The argument 'byteLength' is invalid. Received ${byteLength}`); + } + return webByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256))); + } + var webRandomBytes = (() => { + const { crypto } = globalThis; + if (crypto != null && typeof crypto.getRandomValues === "function") { + return (byteLength) => { + return crypto.getRandomValues(webByteUtils.allocate(byteLength)); + }; + } else { + if (isReactNative()) { + const { console } = globalThis; + console?.warn?.("BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values."); + } + return webMathRandomBytes; + } + })(); + var HEX_DIGIT = /(\d|[a-f])/i; + var webByteUtils = { + toLocalBufferType(potentialUint8array) { + const stringTag = potentialUint8array?.[Symbol.toStringTag] ?? Object.prototype.toString.call(potentialUint8array); + if (stringTag === "Uint8Array") { + return potentialUint8array; + } + if (ArrayBuffer.isView(potentialUint8array)) { + return new Uint8Array(potentialUint8array.buffer.slice(potentialUint8array.byteOffset, potentialUint8array.byteOffset + potentialUint8array.byteLength)); + } + if (stringTag === "ArrayBuffer" || stringTag === "SharedArrayBuffer" || stringTag === "[object ArrayBuffer]" || stringTag === "[object SharedArrayBuffer]") { + return new Uint8Array(potentialUint8array); + } + throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`); + }, + allocate(size) { + if (typeof size !== "number") { + throw new TypeError(`The "size" argument must be of type number. Received ${String(size)}`); + } + return new Uint8Array(size); + }, + equals(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + for (let i = 0; i < a.byteLength; i++) { + if (a[i] !== b[i]) { + return false; + } + } + return true; + }, + fromNumberArray(array) { + return Uint8Array.from(array); + }, + fromBase64(base64) { + return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)); + }, + toBase64(uint8array) { + return btoa(webByteUtils.toISO88591(uint8array)); + }, + fromISO88591(codePoints) { + return Uint8Array.from(codePoints, (c) => c.charCodeAt(0) & 255); + }, + toISO88591(uint8array) { + return Array.from(Uint16Array.from(uint8array), (b) => String.fromCharCode(b)).join(""); + }, + fromHex(hex) { + const evenLengthHex = hex.length % 2 === 0 ? hex : hex.slice(0, hex.length - 1); + const buffer2 = []; + for (let i = 0; i < evenLengthHex.length; i += 2) { + const firstDigit = evenLengthHex[i]; + const secondDigit = evenLengthHex[i + 1]; + if (!HEX_DIGIT.test(firstDigit)) { + break; + } + if (!HEX_DIGIT.test(secondDigit)) { + break; + } + const hexDigit = Number.parseInt(`${firstDigit}${secondDigit}`, 16); + buffer2.push(hexDigit); + } + return Uint8Array.from(buffer2); + }, + toHex(uint8array) { + return Array.from(uint8array, (byte) => byte.toString(16).padStart(2, "0")).join(""); + }, + fromUTF8(text) { + return new TextEncoder().encode(text); + }, + toUTF8(uint8array, start, end, fatal) { + const basicLatin = end - start <= 20 ? tryLatin(uint8array, start, end) : null; + if (basicLatin != null) { + return basicLatin; + } + if (fatal) { + try { + return new TextDecoder("utf8", { fatal }).decode(uint8array.slice(start, end)); + } catch (cause) { + throw new BSONError("Invalid UTF-8 string in BSON document", { cause }); + } + } + return new TextDecoder("utf8", { fatal }).decode(uint8array.slice(start, end)); + }, + utf8ByteLength(input) { + return webByteUtils.fromUTF8(input).byteLength; + }, + encodeUTF8Into(buffer2, source, byteOffset) { + const bytes = webByteUtils.fromUTF8(source); + buffer2.set(bytes, byteOffset); + return bytes.byteLength; + }, + randomBytes: webRandomBytes + }; + var hasGlobalBuffer = typeof Buffer === "function" && Buffer.prototype?._isBuffer !== true; + var ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils; + var BSONDataView = class extends DataView { + static fromUint8Array(input) { + return new DataView(input.buffer, input.byteOffset, input.byteLength); + } + }; + var BSONValue = class { + get [Symbol.for("@@mdb.bson.version")]() { + return BSON_MAJOR_VERSION; + } + [Symbol.for("nodejs.util.inspect.custom")](depth, options, inspect) { + return this.inspect(depth, options, inspect); + } + }; + var Binary = class _Binary extends BSONValue { + get _bsontype() { + return "Binary"; + } + constructor(buffer2, subType) { + super(); + if (!(buffer2 == null) && typeof buffer2 === "string" && !ArrayBuffer.isView(buffer2) && !isAnyArrayBuffer(buffer2) && !Array.isArray(buffer2)) { + throw new BSONError("Binary can only be constructed from Uint8Array or number[]"); + } + this.sub_type = subType ?? _Binary.BSON_BINARY_SUBTYPE_DEFAULT; + if (buffer2 == null) { + this.buffer = ByteUtils.allocate(_Binary.BUFFER_SIZE); + this.position = 0; + } else { + this.buffer = Array.isArray(buffer2) ? ByteUtils.fromNumberArray(buffer2) : ByteUtils.toLocalBufferType(buffer2); + this.position = this.buffer.byteLength; + } + } + put(byteValue) { + if (typeof byteValue === "string" && byteValue.length !== 1) { + throw new BSONError("only accepts single character String"); + } else if (typeof byteValue !== "number" && byteValue.length !== 1) + throw new BSONError("only accepts single character Uint8Array or Array"); + let decodedByte; + if (typeof byteValue === "string") { + decodedByte = byteValue.charCodeAt(0); + } else if (typeof byteValue === "number") { + decodedByte = byteValue; + } else { + decodedByte = byteValue[0]; + } + if (decodedByte < 0 || decodedByte > 255) { + throw new BSONError("only accepts number in a valid unsigned byte range 0-255"); + } + if (this.buffer.byteLength > this.position) { + this.buffer[this.position++] = decodedByte; + } else { + const newSpace = ByteUtils.allocate(_Binary.BUFFER_SIZE + this.buffer.length); + newSpace.set(this.buffer, 0); + this.buffer = newSpace; + this.buffer[this.position++] = decodedByte; + } + } + write(sequence, offset) { + offset = typeof offset === "number" ? offset : this.position; + if (this.buffer.byteLength < offset + sequence.length) { + const newSpace = ByteUtils.allocate(this.buffer.byteLength + sequence.length); + newSpace.set(this.buffer, 0); + this.buffer = newSpace; + } + if (ArrayBuffer.isView(sequence)) { + this.buffer.set(ByteUtils.toLocalBufferType(sequence), offset); + this.position = offset + sequence.byteLength > this.position ? offset + sequence.length : this.position; + } else if (typeof sequence === "string") { + throw new BSONError("input cannot be string"); + } + } + read(position, length) { + length = length && length > 0 ? length : this.position; + return this.buffer.slice(position, position + length); + } + value() { + return this.buffer.length === this.position ? this.buffer : this.buffer.subarray(0, this.position); + } + length() { + return this.position; + } + toJSON() { + return ByteUtils.toBase64(this.buffer); + } + toString(encoding) { + if (encoding === "hex") + return ByteUtils.toHex(this.buffer); + if (encoding === "base64") + return ByteUtils.toBase64(this.buffer); + if (encoding === "utf8" || encoding === "utf-8") + return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false); + return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false); + } + toExtendedJSON(options) { + options = options || {}; + const base64String = ByteUtils.toBase64(this.buffer); + const subType = Number(this.sub_type).toString(16); + if (options.legacy) { + return { + $binary: base64String, + $type: subType.length === 1 ? "0" + subType : subType + }; + } + return { + $binary: { + base64: base64String, + subType: subType.length === 1 ? "0" + subType : subType + } + }; + } + toUUID() { + if (this.sub_type === _Binary.SUBTYPE_UUID) { + return new UUID(this.buffer.slice(0, this.position)); + } + throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${_Binary.SUBTYPE_UUID}" is currently supported.`); + } + static createFromHexString(hex, subType) { + return new _Binary(ByteUtils.fromHex(hex), subType); + } + static createFromBase64(base64, subType) { + return new _Binary(ByteUtils.fromBase64(base64), subType); + } + static fromExtendedJSON(doc, options) { + options = options || {}; + let data; + let type; + if ("$binary" in doc) { + if (options.legacy && typeof doc.$binary === "string" && "$type" in doc) { + type = doc.$type ? parseInt(doc.$type, 16) : 0; + data = ByteUtils.fromBase64(doc.$binary); + } else { + if (typeof doc.$binary !== "string") { + type = doc.$binary.subType ? parseInt(doc.$binary.subType, 16) : 0; + data = ByteUtils.fromBase64(doc.$binary.base64); + } + } + } else if ("$uuid" in doc) { + type = 4; + data = UUID.bytesFromString(doc.$uuid); + } + if (!data) { + throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`); + } + return type === BSON_BINARY_SUBTYPE_UUID_NEW ? new UUID(data) : new _Binary(data, type); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + const base64 = ByteUtils.toBase64(this.buffer.subarray(0, this.position)); + const base64Arg = inspect(base64, options); + const subTypeArg = inspect(this.sub_type, options); + return `Binary.createFromBase64(${base64Arg}, ${subTypeArg})`; + } + }; + Binary.BSON_BINARY_SUBTYPE_DEFAULT = 0; + Binary.BUFFER_SIZE = 256; + Binary.SUBTYPE_DEFAULT = 0; + Binary.SUBTYPE_FUNCTION = 1; + Binary.SUBTYPE_BYTE_ARRAY = 2; + Binary.SUBTYPE_UUID_OLD = 3; + Binary.SUBTYPE_UUID = 4; + Binary.SUBTYPE_MD5 = 5; + Binary.SUBTYPE_ENCRYPTED = 6; + Binary.SUBTYPE_COLUMN = 7; + Binary.SUBTYPE_USER_DEFINED = 128; + var UUID_BYTE_LENGTH = 16; + var UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i; + var UUID_WITH_DASHES = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i; + var UUID = class _UUID extends Binary { + constructor(input) { + let bytes; + if (input == null) { + bytes = _UUID.generate(); + } else if (input instanceof _UUID) { + bytes = ByteUtils.toLocalBufferType(new Uint8Array(input.buffer)); + } else if (ArrayBuffer.isView(input) && input.byteLength === UUID_BYTE_LENGTH) { + bytes = ByteUtils.toLocalBufferType(input); + } else if (typeof input === "string") { + bytes = _UUID.bytesFromString(input); + } else { + throw new BSONError("Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)."); + } + super(bytes, BSON_BINARY_SUBTYPE_UUID_NEW); + } + get id() { + return this.buffer; + } + set id(value) { + this.buffer = value; + } + toHexString(includeDashes = true) { + if (includeDashes) { + return [ + ByteUtils.toHex(this.buffer.subarray(0, 4)), + ByteUtils.toHex(this.buffer.subarray(4, 6)), + ByteUtils.toHex(this.buffer.subarray(6, 8)), + ByteUtils.toHex(this.buffer.subarray(8, 10)), + ByteUtils.toHex(this.buffer.subarray(10, 16)) + ].join("-"); + } + return ByteUtils.toHex(this.buffer); + } + toString(encoding) { + if (encoding === "hex") + return ByteUtils.toHex(this.id); + if (encoding === "base64") + return ByteUtils.toBase64(this.id); + return this.toHexString(); + } + toJSON() { + return this.toHexString(); + } + equals(otherId) { + if (!otherId) { + return false; + } + if (otherId instanceof _UUID) { + return ByteUtils.equals(otherId.id, this.id); + } + try { + return ByteUtils.equals(new _UUID(otherId).id, this.id); + } catch { + return false; + } + } + toBinary() { + return new Binary(this.id, Binary.SUBTYPE_UUID); + } + static generate() { + const bytes = ByteUtils.randomBytes(UUID_BYTE_LENGTH); + bytes[6] = bytes[6] & 15 | 64; + bytes[8] = bytes[8] & 63 | 128; + return bytes; + } + static isValid(input) { + if (!input) { + return false; + } + if (typeof input === "string") { + return _UUID.isValidUUIDString(input); + } + if (isUint8Array(input)) { + return input.byteLength === UUID_BYTE_LENGTH; + } + return input._bsontype === "Binary" && input.sub_type === this.SUBTYPE_UUID && input.buffer.byteLength === 16; + } + static createFromHexString(hexString) { + const buffer2 = _UUID.bytesFromString(hexString); + return new _UUID(buffer2); + } + static createFromBase64(base64) { + return new _UUID(ByteUtils.fromBase64(base64)); + } + static bytesFromString(representation) { + if (!_UUID.isValidUUIDString(representation)) { + throw new BSONError("UUID string representation must be 32 hex digits or canonical hyphenated representation"); + } + return ByteUtils.fromHex(representation.replace(/-/g, "")); + } + static isValidUUIDString(representation) { + return UUID_WITHOUT_DASHES.test(representation) || UUID_WITH_DASHES.test(representation); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + return `new UUID(${inspect(this.toHexString(), options)})`; + } + }; + var Code = class _Code extends BSONValue { + get _bsontype() { + return "Code"; + } + constructor(code, scope) { + super(); + this.code = code.toString(); + this.scope = scope ?? null; + } + toJSON() { + if (this.scope != null) { + return { code: this.code, scope: this.scope }; + } + return { code: this.code }; + } + toExtendedJSON() { + if (this.scope) { + return { $code: this.code, $scope: this.scope }; + } + return { $code: this.code }; + } + static fromExtendedJSON(doc) { + return new _Code(doc.$code, doc.$scope); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + let parametersString = inspect(this.code, options); + const multiLineFn = parametersString.includes("\n"); + if (this.scope != null) { + parametersString += `,${multiLineFn ? "\n" : " "}${inspect(this.scope, options)}`; + } + const endingNewline = multiLineFn && this.scope === null; + return `new Code(${multiLineFn ? "\n" : ""}${parametersString}${endingNewline ? "\n" : ""})`; + } + }; + function isDBRefLike(value) { + return value != null && typeof value === "object" && "$id" in value && value.$id != null && "$ref" in value && typeof value.$ref === "string" && (!("$db" in value) || "$db" in value && typeof value.$db === "string"); + } + var DBRef = class _DBRef extends BSONValue { + get _bsontype() { + return "DBRef"; + } + constructor(collection, oid, db, fields) { + super(); + const parts = collection.split("."); + if (parts.length === 2) { + db = parts.shift(); + collection = parts.shift(); + } + this.collection = collection; + this.oid = oid; + this.db = db; + this.fields = fields || {}; + } + get namespace() { + return this.collection; + } + set namespace(value) { + this.collection = value; + } + toJSON() { + const o = Object.assign({ + $ref: this.collection, + $id: this.oid + }, this.fields); + if (this.db != null) + o.$db = this.db; + return o; + } + toExtendedJSON(options) { + options = options || {}; + let o = { + $ref: this.collection, + $id: this.oid + }; + if (options.legacy) { + return o; + } + if (this.db) + o.$db = this.db; + o = Object.assign(o, this.fields); + return o; + } + static fromExtendedJSON(doc) { + const copy = Object.assign({}, doc); + delete copy.$ref; + delete copy.$id; + delete copy.$db; + return new _DBRef(doc.$ref, doc.$id, doc.$db, copy); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + const args = [ + inspect(this.namespace, options), + inspect(this.oid, options), + ...this.db ? [inspect(this.db, options)] : [], + ...Object.keys(this.fields).length > 0 ? [inspect(this.fields, options)] : [] + ]; + args[1] = inspect === defaultInspect ? `new ObjectId(${args[1]})` : args[1]; + return `new DBRef(${args.join(", ")})`; + } + }; + var wasm = void 0; + try { + wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11])), {}).exports; + } catch { + } + var TWO_PWR_16_DBL = 1 << 16; + var TWO_PWR_24_DBL = 1 << 24; + var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; + var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; + var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; + var INT_CACHE = {}; + var UINT_CACHE = {}; + var MAX_INT64_STRING_LENGTH = 20; + var DECIMAL_REG_EX = /^(\+?0|(\+|-)?[1-9][0-9]*)$/; + var Long = class _Long extends BSONValue { + get _bsontype() { + return "Long"; + } + get __isLong__() { + return true; + } + constructor(low = 0, high, unsigned) { + super(); + if (typeof low === "bigint") { + Object.assign(this, _Long.fromBigInt(low, !!high)); + } else if (typeof low === "string") { + Object.assign(this, _Long.fromString(low, !!high)); + } else { + this.low = low | 0; + this.high = high | 0; + this.unsigned = !!unsigned; + } + } + static fromBits(lowBits, highBits, unsigned) { + return new _Long(lowBits, highBits, unsigned); + } + static fromInt(value, unsigned) { + let obj, cachedObj, cache; + if (unsigned) { + value >>>= 0; + if (cache = 0 <= value && value < 256) { + cachedObj = UINT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = _Long.fromBits(value, (value | 0) < 0 ? -1 : 0, true); + if (cache) + UINT_CACHE[value] = obj; + return obj; + } else { + value |= 0; + if (cache = -128 <= value && value < 128) { + cachedObj = INT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = _Long.fromBits(value, value < 0 ? -1 : 0, false); + if (cache) + INT_CACHE[value] = obj; + return obj; + } + } + static fromNumber(value, unsigned) { + if (isNaN(value)) + return unsigned ? _Long.UZERO : _Long.ZERO; + if (unsigned) { + if (value < 0) + return _Long.UZERO; + if (value >= TWO_PWR_64_DBL) + return _Long.MAX_UNSIGNED_VALUE; + } else { + if (value <= -TWO_PWR_63_DBL) + return _Long.MIN_VALUE; + if (value + 1 >= TWO_PWR_63_DBL) + return _Long.MAX_VALUE; + } + if (value < 0) + return _Long.fromNumber(-value, unsigned).neg(); + return _Long.fromBits(value % TWO_PWR_32_DBL | 0, value / TWO_PWR_32_DBL | 0, unsigned); + } + static fromBigInt(value, unsigned) { + return _Long.fromString(value.toString(), unsigned); + } + static fromString(str, unsigned, radix) { + if (str.length === 0) + throw new BSONError("empty string"); + if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") + return _Long.ZERO; + if (typeof unsigned === "number") { + radix = unsigned, unsigned = false; + } else { + unsigned = !!unsigned; + } + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw new BSONError("radix"); + let p; + if ((p = str.indexOf("-")) > 0) + throw new BSONError("interior hyphen"); + else if (p === 0) { + return _Long.fromString(str.substring(1), unsigned, radix).neg(); + } + const radixToPower = _Long.fromNumber(Math.pow(radix, 8)); + let result = _Long.ZERO; + for (let i = 0; i < str.length; i += 8) { + const size = Math.min(8, str.length - i), value = parseInt(str.substring(i, i + size), radix); + if (size < 8) { + const power = _Long.fromNumber(Math.pow(radix, size)); + result = result.mul(power).add(_Long.fromNumber(value)); + } else { + result = result.mul(radixToPower); + result = result.add(_Long.fromNumber(value)); + } + } + result.unsigned = unsigned; + return result; + } + static fromBytes(bytes, unsigned, le) { + return le ? _Long.fromBytesLE(bytes, unsigned) : _Long.fromBytesBE(bytes, unsigned); + } + static fromBytesLE(bytes, unsigned) { + return new _Long(bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24, bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24, unsigned); + } + static fromBytesBE(bytes, unsigned) { + return new _Long(bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7], bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], unsigned); + } + static isLong(value) { + return value != null && typeof value === "object" && "__isLong__" in value && value.__isLong__ === true; + } + static fromValue(val, unsigned) { + if (typeof val === "number") + return _Long.fromNumber(val, unsigned); + if (typeof val === "string") + return _Long.fromString(val, unsigned); + return _Long.fromBits(val.low, val.high, typeof unsigned === "boolean" ? unsigned : val.unsigned); + } + add(addend) { + if (!_Long.isLong(addend)) + addend = _Long.fromValue(addend); + const a48 = this.high >>> 16; + const a32 = this.high & 65535; + const a16 = this.low >>> 16; + const a00 = this.low & 65535; + const b48 = addend.high >>> 16; + const b32 = addend.high & 65535; + const b16 = addend.low >>> 16; + const b00 = addend.low & 65535; + let c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 + b00; + c16 += c00 >>> 16; + c00 &= 65535; + c16 += a16 + b16; + c32 += c16 >>> 16; + c16 &= 65535; + c32 += a32 + b32; + c48 += c32 >>> 16; + c32 &= 65535; + c48 += a48 + b48; + c48 &= 65535; + return _Long.fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); + } + and(other) { + if (!_Long.isLong(other)) + other = _Long.fromValue(other); + return _Long.fromBits(this.low & other.low, this.high & other.high, this.unsigned); + } + compare(other) { + if (!_Long.isLong(other)) + other = _Long.fromValue(other); + if (this.eq(other)) + return 0; + const thisNeg = this.isNegative(), otherNeg = other.isNegative(); + if (thisNeg && !otherNeg) + return -1; + if (!thisNeg && otherNeg) + return 1; + if (!this.unsigned) + return this.sub(other).isNegative() ? -1 : 1; + return other.high >>> 0 > this.high >>> 0 || other.high === this.high && other.low >>> 0 > this.low >>> 0 ? -1 : 1; + } + comp(other) { + return this.compare(other); + } + divide(divisor) { + if (!_Long.isLong(divisor)) + divisor = _Long.fromValue(divisor); + if (divisor.isZero()) + throw new BSONError("division by zero"); + if (wasm) { + if (!this.unsigned && this.high === -2147483648 && divisor.low === -1 && divisor.high === -1) { + return this; + } + const low = (this.unsigned ? wasm.div_u : wasm.div_s)(this.low, this.high, divisor.low, divisor.high); + return _Long.fromBits(low, wasm.get_high(), this.unsigned); + } + if (this.isZero()) + return this.unsigned ? _Long.UZERO : _Long.ZERO; + let approx, rem, res; + if (!this.unsigned) { + if (this.eq(_Long.MIN_VALUE)) { + if (divisor.eq(_Long.ONE) || divisor.eq(_Long.NEG_ONE)) + return _Long.MIN_VALUE; + else if (divisor.eq(_Long.MIN_VALUE)) + return _Long.ONE; + else { + const halfThis = this.shr(1); + approx = halfThis.div(divisor).shl(1); + if (approx.eq(_Long.ZERO)) { + return divisor.isNegative() ? _Long.ONE : _Long.NEG_ONE; + } else { + rem = this.sub(divisor.mul(approx)); + res = approx.add(rem.div(divisor)); + return res; + } + } + } else if (divisor.eq(_Long.MIN_VALUE)) + return this.unsigned ? _Long.UZERO : _Long.ZERO; + if (this.isNegative()) { + if (divisor.isNegative()) + return this.neg().div(divisor.neg()); + return this.neg().div(divisor).neg(); + } else if (divisor.isNegative()) + return this.div(divisor.neg()).neg(); + res = _Long.ZERO; + } else { + if (!divisor.unsigned) + divisor = divisor.toUnsigned(); + if (divisor.gt(this)) + return _Long.UZERO; + if (divisor.gt(this.shru(1))) + return _Long.UONE; + res = _Long.UZERO; + } + rem = this; + while (rem.gte(divisor)) { + approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber())); + const log2 = Math.ceil(Math.log(approx) / Math.LN2); + const delta = log2 <= 48 ? 1 : Math.pow(2, log2 - 48); + let approxRes = _Long.fromNumber(approx); + let approxRem = approxRes.mul(divisor); + while (approxRem.isNegative() || approxRem.gt(rem)) { + approx -= delta; + approxRes = _Long.fromNumber(approx, this.unsigned); + approxRem = approxRes.mul(divisor); + } + if (approxRes.isZero()) + approxRes = _Long.ONE; + res = res.add(approxRes); + rem = rem.sub(approxRem); + } + return res; + } + div(divisor) { + return this.divide(divisor); + } + equals(other) { + if (!_Long.isLong(other)) + other = _Long.fromValue(other); + if (this.unsigned !== other.unsigned && this.high >>> 31 === 1 && other.high >>> 31 === 1) + return false; + return this.high === other.high && this.low === other.low; + } + eq(other) { + return this.equals(other); + } + getHighBits() { + return this.high; + } + getHighBitsUnsigned() { + return this.high >>> 0; + } + getLowBits() { + return this.low; + } + getLowBitsUnsigned() { + return this.low >>> 0; + } + getNumBitsAbs() { + if (this.isNegative()) { + return this.eq(_Long.MIN_VALUE) ? 64 : this.neg().getNumBitsAbs(); + } + const val = this.high !== 0 ? this.high : this.low; + let bit; + for (bit = 31; bit > 0; bit--) + if ((val & 1 << bit) !== 0) + break; + return this.high !== 0 ? bit + 33 : bit + 1; + } + greaterThan(other) { + return this.comp(other) > 0; + } + gt(other) { + return this.greaterThan(other); + } + greaterThanOrEqual(other) { + return this.comp(other) >= 0; + } + gte(other) { + return this.greaterThanOrEqual(other); + } + ge(other) { + return this.greaterThanOrEqual(other); + } + isEven() { + return (this.low & 1) === 0; + } + isNegative() { + return !this.unsigned && this.high < 0; + } + isOdd() { + return (this.low & 1) === 1; + } + isPositive() { + return this.unsigned || this.high >= 0; + } + isZero() { + return this.high === 0 && this.low === 0; + } + lessThan(other) { + return this.comp(other) < 0; + } + lt(other) { + return this.lessThan(other); + } + lessThanOrEqual(other) { + return this.comp(other) <= 0; + } + lte(other) { + return this.lessThanOrEqual(other); + } + modulo(divisor) { + if (!_Long.isLong(divisor)) + divisor = _Long.fromValue(divisor); + if (wasm) { + const low = (this.unsigned ? wasm.rem_u : wasm.rem_s)(this.low, this.high, divisor.low, divisor.high); + return _Long.fromBits(low, wasm.get_high(), this.unsigned); + } + return this.sub(this.div(divisor).mul(divisor)); + } + mod(divisor) { + return this.modulo(divisor); + } + rem(divisor) { + return this.modulo(divisor); + } + multiply(multiplier) { + if (this.isZero()) + return _Long.ZERO; + if (!_Long.isLong(multiplier)) + multiplier = _Long.fromValue(multiplier); + if (wasm) { + const low = wasm.mul(this.low, this.high, multiplier.low, multiplier.high); + return _Long.fromBits(low, wasm.get_high(), this.unsigned); + } + if (multiplier.isZero()) + return _Long.ZERO; + if (this.eq(_Long.MIN_VALUE)) + return multiplier.isOdd() ? _Long.MIN_VALUE : _Long.ZERO; + if (multiplier.eq(_Long.MIN_VALUE)) + return this.isOdd() ? _Long.MIN_VALUE : _Long.ZERO; + if (this.isNegative()) { + if (multiplier.isNegative()) + return this.neg().mul(multiplier.neg()); + else + return this.neg().mul(multiplier).neg(); + } else if (multiplier.isNegative()) + return this.mul(multiplier.neg()).neg(); + if (this.lt(_Long.TWO_PWR_24) && multiplier.lt(_Long.TWO_PWR_24)) + return _Long.fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned); + const a48 = this.high >>> 16; + const a32 = this.high & 65535; + const a16 = this.low >>> 16; + const a00 = this.low & 65535; + const b48 = multiplier.high >>> 16; + const b32 = multiplier.high & 65535; + const b16 = multiplier.low >>> 16; + const b00 = multiplier.low & 65535; + let c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 * b00; + c16 += c00 >>> 16; + c00 &= 65535; + c16 += a16 * b00; + c32 += c16 >>> 16; + c16 &= 65535; + c16 += a00 * b16; + c32 += c16 >>> 16; + c16 &= 65535; + c32 += a32 * b00; + c48 += c32 >>> 16; + c32 &= 65535; + c32 += a16 * b16; + c48 += c32 >>> 16; + c32 &= 65535; + c32 += a00 * b32; + c48 += c32 >>> 16; + c32 &= 65535; + c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; + c48 &= 65535; + return _Long.fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); + } + mul(multiplier) { + return this.multiply(multiplier); + } + negate() { + if (!this.unsigned && this.eq(_Long.MIN_VALUE)) + return _Long.MIN_VALUE; + return this.not().add(_Long.ONE); + } + neg() { + return this.negate(); + } + not() { + return _Long.fromBits(~this.low, ~this.high, this.unsigned); + } + notEquals(other) { + return !this.equals(other); + } + neq(other) { + return this.notEquals(other); + } + ne(other) { + return this.notEquals(other); + } + or(other) { + if (!_Long.isLong(other)) + other = _Long.fromValue(other); + return _Long.fromBits(this.low | other.low, this.high | other.high, this.unsigned); + } + shiftLeft(numBits) { + if (_Long.isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return _Long.fromBits(this.low << numBits, this.high << numBits | this.low >>> 32 - numBits, this.unsigned); + else + return _Long.fromBits(0, this.low << numBits - 32, this.unsigned); + } + shl(numBits) { + return this.shiftLeft(numBits); + } + shiftRight(numBits) { + if (_Long.isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return _Long.fromBits(this.low >>> numBits | this.high << 32 - numBits, this.high >> numBits, this.unsigned); + else + return _Long.fromBits(this.high >> numBits - 32, this.high >= 0 ? 0 : -1, this.unsigned); + } + shr(numBits) { + return this.shiftRight(numBits); + } + shiftRightUnsigned(numBits) { + if (_Long.isLong(numBits)) + numBits = numBits.toInt(); + numBits &= 63; + if (numBits === 0) + return this; + else { + const high = this.high; + if (numBits < 32) { + const low = this.low; + return _Long.fromBits(low >>> numBits | high << 32 - numBits, high >>> numBits, this.unsigned); + } else if (numBits === 32) + return _Long.fromBits(high, 0, this.unsigned); + else + return _Long.fromBits(high >>> numBits - 32, 0, this.unsigned); + } + } + shr_u(numBits) { + return this.shiftRightUnsigned(numBits); + } + shru(numBits) { + return this.shiftRightUnsigned(numBits); + } + subtract(subtrahend) { + if (!_Long.isLong(subtrahend)) + subtrahend = _Long.fromValue(subtrahend); + return this.add(subtrahend.neg()); + } + sub(subtrahend) { + return this.subtract(subtrahend); + } + toInt() { + return this.unsigned ? this.low >>> 0 : this.low; + } + toNumber() { + if (this.unsigned) + return (this.high >>> 0) * TWO_PWR_32_DBL + (this.low >>> 0); + return this.high * TWO_PWR_32_DBL + (this.low >>> 0); + } + toBigInt() { + return BigInt(this.toString()); + } + toBytes(le) { + return le ? this.toBytesLE() : this.toBytesBE(); + } + toBytesLE() { + const hi = this.high, lo = this.low; + return [ + lo & 255, + lo >>> 8 & 255, + lo >>> 16 & 255, + lo >>> 24, + hi & 255, + hi >>> 8 & 255, + hi >>> 16 & 255, + hi >>> 24 + ]; + } + toBytesBE() { + const hi = this.high, lo = this.low; + return [ + hi >>> 24, + hi >>> 16 & 255, + hi >>> 8 & 255, + hi & 255, + lo >>> 24, + lo >>> 16 & 255, + lo >>> 8 & 255, + lo & 255 + ]; + } + toSigned() { + if (!this.unsigned) + return this; + return _Long.fromBits(this.low, this.high, false); + } + toString(radix) { + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw new BSONError("radix"); + if (this.isZero()) + return "0"; + if (this.isNegative()) { + if (this.eq(_Long.MIN_VALUE)) { + const radixLong = _Long.fromNumber(radix), div = this.div(radixLong), rem1 = div.mul(radixLong).sub(this); + return div.toString(radix) + rem1.toInt().toString(radix); + } else + return "-" + this.neg().toString(radix); + } + const radixToPower = _Long.fromNumber(Math.pow(radix, 6), this.unsigned); + let rem = this; + let result = ""; + while (true) { + const remDiv = rem.div(radixToPower); + const intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0; + let digits = intval.toString(radix); + rem = remDiv; + if (rem.isZero()) { + return digits + result; + } else { + while (digits.length < 6) + digits = "0" + digits; + result = "" + digits + result; + } + } + } + toUnsigned() { + if (this.unsigned) + return this; + return _Long.fromBits(this.low, this.high, true); + } + xor(other) { + if (!_Long.isLong(other)) + other = _Long.fromValue(other); + return _Long.fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned); + } + eqz() { + return this.isZero(); + } + le(other) { + return this.lessThanOrEqual(other); + } + toExtendedJSON(options) { + if (options && options.relaxed) + return this.toNumber(); + return { $numberLong: this.toString() }; + } + static fromExtendedJSON(doc, options) { + const { useBigInt64 = false, relaxed = true } = { ...options }; + if (doc.$numberLong.length > MAX_INT64_STRING_LENGTH) { + throw new BSONError("$numberLong string is too long"); + } + if (!DECIMAL_REG_EX.test(doc.$numberLong)) { + throw new BSONError(`$numberLong string "${doc.$numberLong}" is in an invalid format`); + } + if (useBigInt64) { + const bigIntResult = BigInt(doc.$numberLong); + return BigInt.asIntN(64, bigIntResult); + } + const longResult = _Long.fromString(doc.$numberLong); + if (relaxed) { + return longResult.toNumber(); + } + return longResult; + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + const longVal = inspect(this.toString(), options); + const unsignedVal = this.unsigned ? `, ${inspect(this.unsigned, options)}` : ""; + return `new Long(${longVal}${unsignedVal})`; + } + }; + Long.TWO_PWR_24 = Long.fromInt(TWO_PWR_24_DBL); + Long.MAX_UNSIGNED_VALUE = Long.fromBits(4294967295 | 0, 4294967295 | 0, true); + Long.ZERO = Long.fromInt(0); + Long.UZERO = Long.fromInt(0, true); + Long.ONE = Long.fromInt(1); + Long.UONE = Long.fromInt(1, true); + Long.NEG_ONE = Long.fromInt(-1); + Long.MAX_VALUE = Long.fromBits(4294967295 | 0, 2147483647 | 0, false); + Long.MIN_VALUE = Long.fromBits(0, 2147483648 | 0, false); + var PARSE_STRING_REGEXP = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/; + var PARSE_INF_REGEXP = /^(\+|-)?(Infinity|inf)$/i; + var PARSE_NAN_REGEXP = /^(\+|-)?NaN$/i; + var EXPONENT_MAX = 6111; + var EXPONENT_MIN = -6176; + var EXPONENT_BIAS = 6176; + var MAX_DIGITS = 34; + var NAN_BUFFER = ByteUtils.fromNumberArray([ + 124, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ].reverse()); + var INF_NEGATIVE_BUFFER = ByteUtils.fromNumberArray([ + 248, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ].reverse()); + var INF_POSITIVE_BUFFER = ByteUtils.fromNumberArray([ + 120, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ].reverse()); + var EXPONENT_REGEX = /^([-+])?(\d+)?$/; + var COMBINATION_MASK = 31; + var EXPONENT_MASK = 16383; + var COMBINATION_INFINITY = 30; + var COMBINATION_NAN = 31; + function isDigit(value) { + return !isNaN(parseInt(value, 10)); + } + function divideu128(value) { + const DIVISOR = Long.fromNumber(1e3 * 1e3 * 1e3); + let _rem = Long.fromNumber(0); + if (!value.parts[0] && !value.parts[1] && !value.parts[2] && !value.parts[3]) { + return { quotient: value, rem: _rem }; + } + for (let i = 0; i <= 3; i++) { + _rem = _rem.shiftLeft(32); + _rem = _rem.add(new Long(value.parts[i], 0)); + value.parts[i] = _rem.div(DIVISOR).low; + _rem = _rem.modulo(DIVISOR); + } + return { quotient: value, rem: _rem }; + } + function multiply64x2(left, right) { + if (!left && !right) { + return { high: Long.fromNumber(0), low: Long.fromNumber(0) }; + } + const leftHigh = left.shiftRightUnsigned(32); + const leftLow = new Long(left.getLowBits(), 0); + const rightHigh = right.shiftRightUnsigned(32); + const rightLow = new Long(right.getLowBits(), 0); + let productHigh = leftHigh.multiply(rightHigh); + let productMid = leftHigh.multiply(rightLow); + const productMid2 = leftLow.multiply(rightHigh); + let productLow = leftLow.multiply(rightLow); + productHigh = productHigh.add(productMid.shiftRightUnsigned(32)); + productMid = new Long(productMid.getLowBits(), 0).add(productMid2).add(productLow.shiftRightUnsigned(32)); + productHigh = productHigh.add(productMid.shiftRightUnsigned(32)); + productLow = productMid.shiftLeft(32).add(new Long(productLow.getLowBits(), 0)); + return { high: productHigh, low: productLow }; + } + function lessThan(left, right) { + const uhleft = left.high >>> 0; + const uhright = right.high >>> 0; + if (uhleft < uhright) { + return true; + } else if (uhleft === uhright) { + const ulleft = left.low >>> 0; + const ulright = right.low >>> 0; + if (ulleft < ulright) + return true; + } + return false; + } + function invalidErr(string, message) { + throw new BSONError(`"${string}" is not a valid Decimal128 string - ${message}`); + } + var Decimal128 = class _Decimal128 extends BSONValue { + get _bsontype() { + return "Decimal128"; + } + constructor(bytes) { + super(); + if (typeof bytes === "string") { + this.bytes = _Decimal128.fromString(bytes).bytes; + } else if (isUint8Array(bytes)) { + if (bytes.byteLength !== 16) { + throw new BSONError("Decimal128 must take a Buffer of 16 bytes"); + } + this.bytes = bytes; + } else { + throw new BSONError("Decimal128 must take a Buffer or string"); + } + } + static fromString(representation) { + return _Decimal128._fromString(representation, { allowRounding: false }); + } + static fromStringWithRounding(representation) { + return _Decimal128._fromString(representation, { allowRounding: true }); + } + static _fromString(representation, options) { + let isNegative = false; + let sawSign = false; + let sawRadix = false; + let foundNonZero = false; + let significantDigits = 0; + let nDigitsRead = 0; + let nDigits = 0; + let radixPosition = 0; + let firstNonZero = 0; + const digits = [0]; + let nDigitsStored = 0; + let digitsInsert = 0; + let lastDigit = 0; + let exponent = 0; + let significandHigh = new Long(0, 0); + let significandLow = new Long(0, 0); + let biasedExponent = 0; + let index = 0; + if (representation.length >= 7e3) { + throw new BSONError("" + representation + " not a valid Decimal128 string"); + } + const stringMatch = representation.match(PARSE_STRING_REGEXP); + const infMatch = representation.match(PARSE_INF_REGEXP); + const nanMatch = representation.match(PARSE_NAN_REGEXP); + if (!stringMatch && !infMatch && !nanMatch || representation.length === 0) { + throw new BSONError("" + representation + " not a valid Decimal128 string"); + } + if (stringMatch) { + const unsignedNumber = stringMatch[2]; + const e = stringMatch[4]; + const expSign = stringMatch[5]; + const expNumber = stringMatch[6]; + if (e && expNumber === void 0) + invalidErr(representation, "missing exponent power"); + if (e && unsignedNumber === void 0) + invalidErr(representation, "missing exponent base"); + if (e === void 0 && (expSign || expNumber)) { + invalidErr(representation, "missing e before exponent"); + } + } + if (representation[index] === "+" || representation[index] === "-") { + sawSign = true; + isNegative = representation[index++] === "-"; + } + if (!isDigit(representation[index]) && representation[index] !== ".") { + if (representation[index] === "i" || representation[index] === "I") { + return new _Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER); + } else if (representation[index] === "N") { + return new _Decimal128(NAN_BUFFER); + } + } + while (isDigit(representation[index]) || representation[index] === ".") { + if (representation[index] === ".") { + if (sawRadix) + invalidErr(representation, "contains multiple periods"); + sawRadix = true; + index = index + 1; + continue; + } + if (nDigitsStored < MAX_DIGITS) { + if (representation[index] !== "0" || foundNonZero) { + if (!foundNonZero) { + firstNonZero = nDigitsRead; + } + foundNonZero = true; + digits[digitsInsert++] = parseInt(representation[index], 10); + nDigitsStored = nDigitsStored + 1; + } + } + if (foundNonZero) + nDigits = nDigits + 1; + if (sawRadix) + radixPosition = radixPosition + 1; + nDigitsRead = nDigitsRead + 1; + index = index + 1; + } + if (sawRadix && !nDigitsRead) + throw new BSONError("" + representation + " not a valid Decimal128 string"); + if (representation[index] === "e" || representation[index] === "E") { + const match = representation.substr(++index).match(EXPONENT_REGEX); + if (!match || !match[2]) + return new _Decimal128(NAN_BUFFER); + exponent = parseInt(match[0], 10); + index = index + match[0].length; + } + if (representation[index]) + return new _Decimal128(NAN_BUFFER); + if (!nDigitsStored) { + digits[0] = 0; + nDigits = 1; + nDigitsStored = 1; + significantDigits = 0; + } else { + lastDigit = nDigitsStored - 1; + significantDigits = nDigits; + if (significantDigits !== 1) { + while (representation[firstNonZero + significantDigits - 1 + Number(sawSign) + Number(sawRadix)] === "0") { + significantDigits = significantDigits - 1; + } + } + } + if (exponent <= radixPosition && radixPosition > exponent + (1 << 14)) { + exponent = EXPONENT_MIN; + } else { + exponent = exponent - radixPosition; + } + while (exponent > EXPONENT_MAX) { + lastDigit = lastDigit + 1; + if (lastDigit >= MAX_DIGITS) { + if (significantDigits === 0) { + exponent = EXPONENT_MAX; + break; + } + invalidErr(representation, "overflow"); + } + exponent = exponent - 1; + } + if (options.allowRounding) { + while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) { + if (lastDigit === 0 && significantDigits < nDigitsStored) { + exponent = EXPONENT_MIN; + significantDigits = 0; + break; + } + if (nDigitsStored < nDigits) { + nDigits = nDigits - 1; + } else { + lastDigit = lastDigit - 1; + } + if (exponent < EXPONENT_MAX) { + exponent = exponent + 1; + } else { + const digitsString = digits.join(""); + if (digitsString.match(/^0+$/)) { + exponent = EXPONENT_MAX; + break; + } + invalidErr(representation, "overflow"); + } + } + if (lastDigit + 1 < significantDigits) { + let endOfString = nDigitsRead; + if (sawRadix) { + firstNonZero = firstNonZero + 1; + endOfString = endOfString + 1; + } + if (sawSign) { + firstNonZero = firstNonZero + 1; + endOfString = endOfString + 1; + } + const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10); + let roundBit = 0; + if (roundDigit >= 5) { + roundBit = 1; + if (roundDigit === 5) { + roundBit = digits[lastDigit] % 2 === 1 ? 1 : 0; + for (let i = firstNonZero + lastDigit + 2; i < endOfString; i++) { + if (parseInt(representation[i], 10)) { + roundBit = 1; + break; + } + } + } + } + if (roundBit) { + let dIdx = lastDigit; + for (; dIdx >= 0; dIdx--) { + if (++digits[dIdx] > 9) { + digits[dIdx] = 0; + if (dIdx === 0) { + if (exponent < EXPONENT_MAX) { + exponent = exponent + 1; + digits[dIdx] = 1; + } else { + return new _Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER); + } + } + } else { + break; + } + } + } + } + } else { + while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) { + if (lastDigit === 0) { + if (significantDigits === 0) { + exponent = EXPONENT_MIN; + break; + } + invalidErr(representation, "exponent underflow"); + } + if (nDigitsStored < nDigits) { + if (representation[nDigits - 1 + Number(sawSign) + Number(sawRadix)] !== "0" && significantDigits !== 0) { + invalidErr(representation, "inexact rounding"); + } + nDigits = nDigits - 1; + } else { + if (digits[lastDigit] !== 0) { + invalidErr(representation, "inexact rounding"); + } + lastDigit = lastDigit - 1; + } + if (exponent < EXPONENT_MAX) { + exponent = exponent + 1; + } else { + invalidErr(representation, "overflow"); + } + } + if (lastDigit + 1 < significantDigits) { + if (sawRadix) { + firstNonZero = firstNonZero + 1; + } + if (sawSign) { + firstNonZero = firstNonZero + 1; + } + const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10); + if (roundDigit !== 0) { + invalidErr(representation, "inexact rounding"); + } + } + } + significandHigh = Long.fromNumber(0); + significandLow = Long.fromNumber(0); + if (significantDigits === 0) { + significandHigh = Long.fromNumber(0); + significandLow = Long.fromNumber(0); + } else if (lastDigit < 17) { + let dIdx = 0; + significandLow = Long.fromNumber(digits[dIdx++]); + significandHigh = new Long(0, 0); + for (; dIdx <= lastDigit; dIdx++) { + significandLow = significandLow.multiply(Long.fromNumber(10)); + significandLow = significandLow.add(Long.fromNumber(digits[dIdx])); + } + } else { + let dIdx = 0; + significandHigh = Long.fromNumber(digits[dIdx++]); + for (; dIdx <= lastDigit - 17; dIdx++) { + significandHigh = significandHigh.multiply(Long.fromNumber(10)); + significandHigh = significandHigh.add(Long.fromNumber(digits[dIdx])); + } + significandLow = Long.fromNumber(digits[dIdx++]); + for (; dIdx <= lastDigit; dIdx++) { + significandLow = significandLow.multiply(Long.fromNumber(10)); + significandLow = significandLow.add(Long.fromNumber(digits[dIdx])); + } + } + const significand = multiply64x2(significandHigh, Long.fromString("100000000000000000")); + significand.low = significand.low.add(significandLow); + if (lessThan(significand.low, significandLow)) { + significand.high = significand.high.add(Long.fromNumber(1)); + } + biasedExponent = exponent + EXPONENT_BIAS; + const dec = { low: Long.fromNumber(0), high: Long.fromNumber(0) }; + if (significand.high.shiftRightUnsigned(49).and(Long.fromNumber(1)).equals(Long.fromNumber(1))) { + dec.high = dec.high.or(Long.fromNumber(3).shiftLeft(61)); + dec.high = dec.high.or(Long.fromNumber(biasedExponent).and(Long.fromNumber(16383).shiftLeft(47))); + dec.high = dec.high.or(significand.high.and(Long.fromNumber(140737488355327))); + } else { + dec.high = dec.high.or(Long.fromNumber(biasedExponent & 16383).shiftLeft(49)); + dec.high = dec.high.or(significand.high.and(Long.fromNumber(562949953421311))); + } + dec.low = significand.low; + if (isNegative) { + dec.high = dec.high.or(Long.fromString("9223372036854775808")); + } + const buffer2 = ByteUtils.allocate(16); + index = 0; + buffer2[index++] = dec.low.low & 255; + buffer2[index++] = dec.low.low >> 8 & 255; + buffer2[index++] = dec.low.low >> 16 & 255; + buffer2[index++] = dec.low.low >> 24 & 255; + buffer2[index++] = dec.low.high & 255; + buffer2[index++] = dec.low.high >> 8 & 255; + buffer2[index++] = dec.low.high >> 16 & 255; + buffer2[index++] = dec.low.high >> 24 & 255; + buffer2[index++] = dec.high.low & 255; + buffer2[index++] = dec.high.low >> 8 & 255; + buffer2[index++] = dec.high.low >> 16 & 255; + buffer2[index++] = dec.high.low >> 24 & 255; + buffer2[index++] = dec.high.high & 255; + buffer2[index++] = dec.high.high >> 8 & 255; + buffer2[index++] = dec.high.high >> 16 & 255; + buffer2[index++] = dec.high.high >> 24 & 255; + return new _Decimal128(buffer2); + } + toString() { + let biased_exponent; + let significand_digits = 0; + const significand = new Array(36); + for (let i = 0; i < significand.length; i++) + significand[i] = 0; + let index = 0; + let is_zero = false; + let significand_msb; + let significand128 = { parts: [0, 0, 0, 0] }; + let j, k; + const string = []; + index = 0; + const buffer2 = this.bytes; + const low = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + const midl = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + const midh = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + const high = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + index = 0; + const dec = { + low: new Long(low, midl), + high: new Long(midh, high) + }; + if (dec.high.lessThan(Long.ZERO)) { + string.push("-"); + } + const combination = high >> 26 & COMBINATION_MASK; + if (combination >> 3 === 3) { + if (combination === COMBINATION_INFINITY) { + return string.join("") + "Infinity"; + } else if (combination === COMBINATION_NAN) { + return "NaN"; + } else { + biased_exponent = high >> 15 & EXPONENT_MASK; + significand_msb = 8 + (high >> 14 & 1); + } + } else { + significand_msb = high >> 14 & 7; + biased_exponent = high >> 17 & EXPONENT_MASK; + } + const exponent = biased_exponent - EXPONENT_BIAS; + significand128.parts[0] = (high & 16383) + ((significand_msb & 15) << 14); + significand128.parts[1] = midh; + significand128.parts[2] = midl; + significand128.parts[3] = low; + if (significand128.parts[0] === 0 && significand128.parts[1] === 0 && significand128.parts[2] === 0 && significand128.parts[3] === 0) { + is_zero = true; + } else { + for (k = 3; k >= 0; k--) { + let least_digits = 0; + const result = divideu128(significand128); + significand128 = result.quotient; + least_digits = result.rem.low; + if (!least_digits) + continue; + for (j = 8; j >= 0; j--) { + significand[k * 9 + j] = least_digits % 10; + least_digits = Math.floor(least_digits / 10); + } + } + } + if (is_zero) { + significand_digits = 1; + significand[index] = 0; + } else { + significand_digits = 36; + while (!significand[index]) { + significand_digits = significand_digits - 1; + index = index + 1; + } + } + const scientific_exponent = significand_digits - 1 + exponent; + if (scientific_exponent >= 34 || scientific_exponent <= -7 || exponent > 0) { + if (significand_digits > 34) { + string.push(`${0}`); + if (exponent > 0) + string.push(`E+${exponent}`); + else if (exponent < 0) + string.push(`E${exponent}`); + return string.join(""); + } + string.push(`${significand[index++]}`); + significand_digits = significand_digits - 1; + if (significand_digits) { + string.push("."); + } + for (let i = 0; i < significand_digits; i++) { + string.push(`${significand[index++]}`); + } + string.push("E"); + if (scientific_exponent > 0) { + string.push(`+${scientific_exponent}`); + } else { + string.push(`${scientific_exponent}`); + } + } else { + if (exponent >= 0) { + for (let i = 0; i < significand_digits; i++) { + string.push(`${significand[index++]}`); + } + } else { + let radix_position = significand_digits + exponent; + if (radix_position > 0) { + for (let i = 0; i < radix_position; i++) { + string.push(`${significand[index++]}`); + } + } else { + string.push("0"); + } + string.push("."); + while (radix_position++ < 0) { + string.push("0"); + } + for (let i = 0; i < significand_digits - Math.max(radix_position - 1, 0); i++) { + string.push(`${significand[index++]}`); + } + } + } + return string.join(""); + } + toJSON() { + return { $numberDecimal: this.toString() }; + } + toExtendedJSON() { + return { $numberDecimal: this.toString() }; + } + static fromExtendedJSON(doc) { + return _Decimal128.fromString(doc.$numberDecimal); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + const d128string = inspect(this.toString(), options); + return `new Decimal128(${d128string})`; + } + }; + var Double = class _Double extends BSONValue { + get _bsontype() { + return "Double"; + } + constructor(value) { + super(); + if (value instanceof Number) { + value = value.valueOf(); + } + this.value = +value; + } + valueOf() { + return this.value; + } + toJSON() { + return this.value; + } + toString(radix) { + return this.value.toString(radix); + } + toExtendedJSON(options) { + if (options && (options.legacy || options.relaxed && isFinite(this.value))) { + return this.value; + } + if (Object.is(Math.sign(this.value), -0)) { + return { $numberDouble: "-0.0" }; + } + return { + $numberDouble: Number.isInteger(this.value) ? this.value.toFixed(1) : this.value.toString() + }; + } + static fromExtendedJSON(doc, options) { + const doubleValue = parseFloat(doc.$numberDouble); + return options && options.relaxed ? doubleValue : new _Double(doubleValue); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + return `new Double(${inspect(this.value, options)})`; + } + }; + var Int32 = class _Int32 extends BSONValue { + get _bsontype() { + return "Int32"; + } + constructor(value) { + super(); + if (value instanceof Number) { + value = value.valueOf(); + } + this.value = +value | 0; + } + valueOf() { + return this.value; + } + toString(radix) { + return this.value.toString(radix); + } + toJSON() { + return this.value; + } + toExtendedJSON(options) { + if (options && (options.relaxed || options.legacy)) + return this.value; + return { $numberInt: this.value.toString() }; + } + static fromExtendedJSON(doc, options) { + return options && options.relaxed ? parseInt(doc.$numberInt, 10) : new _Int32(doc.$numberInt); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + return `new Int32(${inspect(this.value, options)})`; + } + }; + var MaxKey = class _MaxKey extends BSONValue { + get _bsontype() { + return "MaxKey"; + } + toExtendedJSON() { + return { $maxKey: 1 }; + } + static fromExtendedJSON() { + return new _MaxKey(); + } + inspect() { + return "new MaxKey()"; + } + }; + var MinKey = class _MinKey extends BSONValue { + get _bsontype() { + return "MinKey"; + } + toExtendedJSON() { + return { $minKey: 1 }; + } + static fromExtendedJSON() { + return new _MinKey(); + } + inspect() { + return "new MinKey()"; + } + }; + var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); + var PROCESS_UNIQUE = null; + var kId = Symbol("id"); + var ObjectId = class _ObjectId extends BSONValue { + get _bsontype() { + return "ObjectId"; + } + constructor(inputId) { + super(); + let workingId; + if (typeof inputId === "object" && inputId && "id" in inputId) { + if (typeof inputId.id !== "string" && !ArrayBuffer.isView(inputId.id)) { + throw new BSONError("Argument passed in must have an id that is of type string or Buffer"); + } + if ("toHexString" in inputId && typeof inputId.toHexString === "function") { + workingId = ByteUtils.fromHex(inputId.toHexString()); + } else { + workingId = inputId.id; + } + } else { + workingId = inputId; + } + if (workingId == null || typeof workingId === "number") { + this[kId] = _ObjectId.generate(typeof workingId === "number" ? workingId : void 0); + } else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) { + this[kId] = ByteUtils.toLocalBufferType(workingId); + } else if (typeof workingId === "string") { + if (workingId.length === 24 && checkForHexRegExp.test(workingId)) { + this[kId] = ByteUtils.fromHex(workingId); + } else { + throw new BSONError("input must be a 24 character hex string, 12 byte Uint8Array, or an integer"); + } + } else { + throw new BSONError("Argument passed in does not match the accepted types"); + } + if (_ObjectId.cacheHexString) { + this.__id = ByteUtils.toHex(this.id); + } + } + get id() { + return this[kId]; + } + set id(value) { + this[kId] = value; + if (_ObjectId.cacheHexString) { + this.__id = ByteUtils.toHex(value); + } + } + toHexString() { + if (_ObjectId.cacheHexString && this.__id) { + return this.__id; + } + const hexString = ByteUtils.toHex(this.id); + if (_ObjectId.cacheHexString && !this.__id) { + this.__id = hexString; + } + return hexString; + } + static getInc() { + return _ObjectId.index = (_ObjectId.index + 1) % 16777215; + } + static generate(time) { + if ("number" !== typeof time) { + time = Math.floor(Date.now() / 1e3); + } + const inc = _ObjectId.getInc(); + const buffer2 = ByteUtils.allocate(12); + BSONDataView.fromUint8Array(buffer2).setUint32(0, time, false); + if (PROCESS_UNIQUE === null) { + PROCESS_UNIQUE = ByteUtils.randomBytes(5); + } + buffer2[4] = PROCESS_UNIQUE[0]; + buffer2[5] = PROCESS_UNIQUE[1]; + buffer2[6] = PROCESS_UNIQUE[2]; + buffer2[7] = PROCESS_UNIQUE[3]; + buffer2[8] = PROCESS_UNIQUE[4]; + buffer2[11] = inc & 255; + buffer2[10] = inc >> 8 & 255; + buffer2[9] = inc >> 16 & 255; + return buffer2; + } + toString(encoding) { + if (encoding === "base64") + return ByteUtils.toBase64(this.id); + if (encoding === "hex") + return this.toHexString(); + return this.toHexString(); + } + toJSON() { + return this.toHexString(); + } + static is(variable) { + return variable != null && typeof variable === "object" && "_bsontype" in variable && variable._bsontype === "ObjectId"; + } + equals(otherId) { + if (otherId === void 0 || otherId === null) { + return false; + } + if (_ObjectId.is(otherId)) { + return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]); + } + if (typeof otherId === "string") { + return otherId.toLowerCase() === this.toHexString(); + } + if (typeof otherId === "object" && typeof otherId.toHexString === "function") { + const otherIdString = otherId.toHexString(); + const thisIdString = this.toHexString(); + return typeof otherIdString === "string" && otherIdString.toLowerCase() === thisIdString; + } + return false; + } + getTimestamp() { + const timestamp = /* @__PURE__ */ new Date(); + const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false); + timestamp.setTime(Math.floor(time) * 1e3); + return timestamp; + } + static createPk() { + return new _ObjectId(); + } + static createFromTime(time) { + const buffer2 = ByteUtils.fromNumberArray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + BSONDataView.fromUint8Array(buffer2).setUint32(0, time, false); + return new _ObjectId(buffer2); + } + static createFromHexString(hexString) { + if (hexString?.length !== 24) { + throw new BSONError("hex string must be 24 characters"); + } + return new _ObjectId(ByteUtils.fromHex(hexString)); + } + static createFromBase64(base64) { + if (base64?.length !== 16) { + throw new BSONError("base64 string must be 16 characters"); + } + return new _ObjectId(ByteUtils.fromBase64(base64)); + } + static isValid(id) { + if (id == null) + return false; + try { + new _ObjectId(id); + return true; + } catch { + return false; + } + } + toExtendedJSON() { + if (this.toHexString) + return { $oid: this.toHexString() }; + return { $oid: this.toString("hex") }; + } + static fromExtendedJSON(doc) { + return new _ObjectId(doc.$oid); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + return `new ObjectId(${inspect(this.toHexString(), options)})`; + } + }; + ObjectId.index = Math.floor(Math.random() * 16777215); + function internalCalculateObjectSize(object, serializeFunctions, ignoreUndefined) { + let totalLength = 4 + 1; + if (Array.isArray(object)) { + for (let i = 0; i < object.length; i++) { + totalLength += calculateElement(i.toString(), object[i], serializeFunctions, true, ignoreUndefined); + } + } else { + if (typeof object?.toBSON === "function") { + object = object.toBSON(); + } + for (const key of Object.keys(object)) { + totalLength += calculateElement(key, object[key], serializeFunctions, false, ignoreUndefined); + } + } + return totalLength; + } + function calculateElement(name, value, serializeFunctions = false, isArray = false, ignoreUndefined = false) { + if (typeof value?.toBSON === "function") { + value = value.toBSON(); + } + switch (typeof value) { + case "string": + return 1 + ByteUtils.utf8ByteLength(name) + 1 + 4 + ByteUtils.utf8ByteLength(value) + 1; + case "number": + if (Math.floor(value) === value && value >= JS_INT_MIN && value <= JS_INT_MAX) { + if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (4 + 1); + } else { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); + } + } else { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); + } + case "undefined": + if (isArray || !ignoreUndefined) + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1; + return 0; + case "boolean": + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 1); + case "object": + if (value != null && typeof value._bsontype === "string" && value[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { + throw new BSONVersionError(); + } else if (value == null || value._bsontype === "MinKey" || value._bsontype === "MaxKey") { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1; + } else if (value._bsontype === "ObjectId") { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (12 + 1); + } else if (value instanceof Date || isDate(value)) { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); + } else if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || isAnyArrayBuffer(value)) { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 4 + 1) + value.byteLength; + } else if (value._bsontype === "Long" || value._bsontype === "Double" || value._bsontype === "Timestamp") { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); + } else if (value._bsontype === "Decimal128") { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (16 + 1); + } else if (value._bsontype === "Code") { + if (value.scope != null && Object.keys(value.scope).length > 0) { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + 4 + ByteUtils.utf8ByteLength(value.code.toString()) + 1 + internalCalculateObjectSize(value.scope, serializeFunctions, ignoreUndefined); + } else { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + ByteUtils.utf8ByteLength(value.code.toString()) + 1; + } + } else if (value._bsontype === "Binary") { + const binary = value; + if (binary.sub_type === Binary.SUBTYPE_BYTE_ARRAY) { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (binary.position + 1 + 4 + 1 + 4); + } else { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (binary.position + 1 + 4 + 1); + } + } else if (value._bsontype === "Symbol") { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + ByteUtils.utf8ByteLength(value.value) + 4 + 1 + 1; + } else if (value._bsontype === "DBRef") { + const ordered_values = Object.assign({ + $ref: value.collection, + $id: value.oid + }, value.fields); + if (value.db != null) { + ordered_values["$db"] = value.db; + } + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + internalCalculateObjectSize(ordered_values, serializeFunctions, ignoreUndefined); + } else if (value instanceof RegExp || isRegExp(value)) { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + ByteUtils.utf8ByteLength(value.source) + 1 + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1; + } else if (value._bsontype === "BSONRegExp") { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + ByteUtils.utf8ByteLength(value.pattern) + 1 + ByteUtils.utf8ByteLength(value.options) + 1; + } else { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + internalCalculateObjectSize(value, serializeFunctions, ignoreUndefined) + 1; + } + case "function": + if (serializeFunctions) { + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + ByteUtils.utf8ByteLength(value.toString()) + 1; + } + } + return 0; + } + function alphabetize(str) { + return str.split("").sort().join(""); + } + var BSONRegExp = class _BSONRegExp extends BSONValue { + get _bsontype() { + return "BSONRegExp"; + } + constructor(pattern, options) { + super(); + this.pattern = pattern; + this.options = alphabetize(options ?? ""); + if (this.pattern.indexOf("\0") !== -1) { + throw new BSONError(`BSON Regex patterns cannot contain null bytes, found: ${JSON.stringify(this.pattern)}`); + } + if (this.options.indexOf("\0") !== -1) { + throw new BSONError(`BSON Regex options cannot contain null bytes, found: ${JSON.stringify(this.options)}`); + } + for (let i = 0; i < this.options.length; i++) { + if (!(this.options[i] === "i" || this.options[i] === "m" || this.options[i] === "x" || this.options[i] === "l" || this.options[i] === "s" || this.options[i] === "u")) { + throw new BSONError(`The regular expression option [${this.options[i]}] is not supported`); + } + } + } + static parseOptions(options) { + return options ? options.split("").sort().join("") : ""; + } + toExtendedJSON(options) { + options = options || {}; + if (options.legacy) { + return { $regex: this.pattern, $options: this.options }; + } + return { $regularExpression: { pattern: this.pattern, options: this.options } }; + } + static fromExtendedJSON(doc) { + if ("$regex" in doc) { + if (typeof doc.$regex !== "string") { + if (doc.$regex._bsontype === "BSONRegExp") { + return doc; + } + } else { + return new _BSONRegExp(doc.$regex, _BSONRegExp.parseOptions(doc.$options)); + } + } + if ("$regularExpression" in doc) { + return new _BSONRegExp(doc.$regularExpression.pattern, _BSONRegExp.parseOptions(doc.$regularExpression.options)); + } + throw new BSONError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`); + } + inspect(depth, options, inspect) { + const stylize = getStylizeFunction(options) ?? ((v) => v); + inspect ??= defaultInspect; + const pattern = stylize(inspect(this.pattern), "regexp"); + const flags = stylize(inspect(this.options), "regexp"); + return `new BSONRegExp(${pattern}, ${flags})`; + } + }; + var BSONSymbol = class _BSONSymbol extends BSONValue { + get _bsontype() { + return "BSONSymbol"; + } + constructor(value) { + super(); + this.value = value; + } + valueOf() { + return this.value; + } + toString() { + return this.value; + } + toJSON() { + return this.value; + } + toExtendedJSON() { + return { $symbol: this.value }; + } + static fromExtendedJSON(doc) { + return new _BSONSymbol(doc.$symbol); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + return `new BSONSymbol(${inspect(this.value, options)})`; + } + }; + var LongWithoutOverridesClass = Long; + var Timestamp = class _Timestamp extends LongWithoutOverridesClass { + get _bsontype() { + return "Timestamp"; + } + constructor(low) { + if (low == null) { + super(0, 0, true); + } else if (typeof low === "bigint") { + super(low, true); + } else if (Long.isLong(low)) { + super(low.low, low.high, true); + } else if (typeof low === "object" && "t" in low && "i" in low) { + if (typeof low.t !== "number" && (typeof low.t !== "object" || low.t._bsontype !== "Int32")) { + throw new BSONError("Timestamp constructed from { t, i } must provide t as a number"); + } + if (typeof low.i !== "number" && (typeof low.i !== "object" || low.i._bsontype !== "Int32")) { + throw new BSONError("Timestamp constructed from { t, i } must provide i as a number"); + } + const t = Number(low.t); + const i = Number(low.i); + if (t < 0 || Number.isNaN(t)) { + throw new BSONError("Timestamp constructed from { t, i } must provide a positive t"); + } + if (i < 0 || Number.isNaN(i)) { + throw new BSONError("Timestamp constructed from { t, i } must provide a positive i"); + } + if (t > 4294967295) { + throw new BSONError("Timestamp constructed from { t, i } must provide t equal or less than uint32 max"); + } + if (i > 4294967295) { + throw new BSONError("Timestamp constructed from { t, i } must provide i equal or less than uint32 max"); + } + super(i, t, true); + } else { + throw new BSONError("A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }"); + } + } + toJSON() { + return { + $timestamp: this.toString() + }; + } + static fromInt(value) { + return new _Timestamp(Long.fromInt(value, true)); + } + static fromNumber(value) { + return new _Timestamp(Long.fromNumber(value, true)); + } + static fromBits(lowBits, highBits) { + return new _Timestamp({ i: lowBits, t: highBits }); + } + static fromString(str, optRadix) { + return new _Timestamp(Long.fromString(str, true, optRadix)); + } + toExtendedJSON() { + return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } }; + } + static fromExtendedJSON(doc) { + const i = Long.isLong(doc.$timestamp.i) ? doc.$timestamp.i.getLowBitsUnsigned() : doc.$timestamp.i; + const t = Long.isLong(doc.$timestamp.t) ? doc.$timestamp.t.getLowBitsUnsigned() : doc.$timestamp.t; + return new _Timestamp({ t, i }); + } + inspect(depth, options, inspect) { + inspect ??= defaultInspect; + const t = inspect(this.high >>> 0, options); + const i = inspect(this.low >>> 0, options); + return `new Timestamp({ t: ${t}, i: ${i} })`; + } + }; + Timestamp.MAX_VALUE = Long.MAX_UNSIGNED_VALUE; + var JS_INT_MAX_LONG = Long.fromNumber(JS_INT_MAX); + var JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN); + function internalDeserialize(buffer2, options, isArray) { + options = options == null ? {} : options; + const index = options && options.index ? options.index : 0; + const size = buffer2[index] | buffer2[index + 1] << 8 | buffer2[index + 2] << 16 | buffer2[index + 3] << 24; + if (size < 5) { + throw new BSONError(`bson size must be >= 5, is ${size}`); + } + if (options.allowObjectSmallerThanBufferSize && buffer2.length < size) { + throw new BSONError(`buffer length ${buffer2.length} must be >= bson size ${size}`); + } + if (!options.allowObjectSmallerThanBufferSize && buffer2.length !== size) { + throw new BSONError(`buffer length ${buffer2.length} must === bson size ${size}`); + } + if (size + index > buffer2.byteLength) { + throw new BSONError(`(bson size ${size} + options.index ${index} must be <= buffer length ${buffer2.byteLength})`); + } + if (buffer2[index + size - 1] !== 0) { + throw new BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00"); + } + return deserializeObject(buffer2, index, options, isArray); + } + var allowedDBRefKeys = /^\$ref$|^\$id$|^\$db$/; + function deserializeObject(buffer2, index, options, isArray = false) { + const fieldsAsRaw = options["fieldsAsRaw"] == null ? null : options["fieldsAsRaw"]; + const raw = options["raw"] == null ? false : options["raw"]; + const bsonRegExp = typeof options["bsonRegExp"] === "boolean" ? options["bsonRegExp"] : false; + const promoteBuffers = options.promoteBuffers ?? false; + const promoteLongs = options.promoteLongs ?? true; + const promoteValues = options.promoteValues ?? true; + const useBigInt64 = options.useBigInt64 ?? false; + if (useBigInt64 && !promoteValues) { + throw new BSONError("Must either request bigint or Long for int64 deserialization"); + } + if (useBigInt64 && !promoteLongs) { + throw new BSONError("Must either request bigint or Long for int64 deserialization"); + } + const validation = options.validation == null ? { utf8: true } : options.validation; + let globalUTFValidation = true; + let validationSetting; + const utf8KeysSet = /* @__PURE__ */ new Set(); + const utf8ValidatedKeys = validation.utf8; + if (typeof utf8ValidatedKeys === "boolean") { + validationSetting = utf8ValidatedKeys; + } else { + globalUTFValidation = false; + const utf8ValidationValues = Object.keys(utf8ValidatedKeys).map(function(key) { + return utf8ValidatedKeys[key]; + }); + if (utf8ValidationValues.length === 0) { + throw new BSONError("UTF-8 validation setting cannot be empty"); + } + if (typeof utf8ValidationValues[0] !== "boolean") { + throw new BSONError("Invalid UTF-8 validation option, must specify boolean values"); + } + validationSetting = utf8ValidationValues[0]; + if (!utf8ValidationValues.every((item) => item === validationSetting)) { + throw new BSONError("Invalid UTF-8 validation option - keys must be all true or all false"); + } + } + if (!globalUTFValidation) { + for (const key of Object.keys(utf8ValidatedKeys)) { + utf8KeysSet.add(key); + } + } + const startIndex = index; + if (buffer2.length < 5) + throw new BSONError("corrupt bson message < 5 bytes long"); + const size = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + if (size < 5 || size > buffer2.length) + throw new BSONError("corrupt bson message"); + const object = isArray ? [] : {}; + let arrayIndex = 0; + const done = false; + let isPossibleDBRef = isArray ? false : null; + const dataview = new DataView(buffer2.buffer, buffer2.byteOffset, buffer2.byteLength); + while (!done) { + const elementType = buffer2[index++]; + if (elementType === 0) + break; + let i = index; + while (buffer2[i] !== 0 && i < buffer2.length) { + i++; + } + if (i >= buffer2.byteLength) + throw new BSONError("Bad BSON Document: illegal CString"); + const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer2, index, i, false); + let shouldValidateKey = true; + if (globalUTFValidation || utf8KeysSet.has(name)) { + shouldValidateKey = validationSetting; + } else { + shouldValidateKey = !validationSetting; + } + if (isPossibleDBRef !== false && name[0] === "$") { + isPossibleDBRef = allowedDBRefKeys.test(name); + } + let value; + index = i + 1; + if (elementType === BSON_DATA_STRING) { + const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) { + throw new BSONError("bad string length in bson"); + } + value = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, shouldValidateKey); + index = index + stringSize; + } else if (elementType === BSON_DATA_OID) { + const oid = ByteUtils.allocate(12); + oid.set(buffer2.subarray(index, index + 12)); + value = new ObjectId(oid); + index = index + 12; + } else if (elementType === BSON_DATA_INT && promoteValues === false) { + value = new Int32(buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24); + } else if (elementType === BSON_DATA_INT) { + value = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + } else if (elementType === BSON_DATA_NUMBER && promoteValues === false) { + value = new Double(dataview.getFloat64(index, true)); + index = index + 8; + } else if (elementType === BSON_DATA_NUMBER) { + value = dataview.getFloat64(index, true); + index = index + 8; + } else if (elementType === BSON_DATA_DATE) { + const lowBits = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + const highBits = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + value = new Date(new Long(lowBits, highBits).toNumber()); + } else if (elementType === BSON_DATA_BOOLEAN) { + if (buffer2[index] !== 0 && buffer2[index] !== 1) + throw new BSONError("illegal boolean type value"); + value = buffer2[index++] === 1; + } else if (elementType === BSON_DATA_OBJECT) { + const _index = index; + const objectSize = buffer2[index] | buffer2[index + 1] << 8 | buffer2[index + 2] << 16 | buffer2[index + 3] << 24; + if (objectSize <= 0 || objectSize > buffer2.length - index) + throw new BSONError("bad embedded document length in bson"); + if (raw) { + value = buffer2.slice(index, index + objectSize); + } else { + let objectOptions = options; + if (!globalUTFValidation) { + objectOptions = { ...options, validation: { utf8: shouldValidateKey } }; + } + value = deserializeObject(buffer2, _index, objectOptions, false); + } + index = index + objectSize; + } else if (elementType === BSON_DATA_ARRAY) { + const _index = index; + const objectSize = buffer2[index] | buffer2[index + 1] << 8 | buffer2[index + 2] << 16 | buffer2[index + 3] << 24; + let arrayOptions = options; + const stopIndex = index + objectSize; + if (fieldsAsRaw && fieldsAsRaw[name]) { + arrayOptions = { ...options, raw: true }; + } + if (!globalUTFValidation) { + arrayOptions = { ...arrayOptions, validation: { utf8: shouldValidateKey } }; + } + value = deserializeObject(buffer2, _index, arrayOptions, true); + index = index + objectSize; + if (buffer2[index - 1] !== 0) + throw new BSONError("invalid array terminator byte"); + if (index !== stopIndex) + throw new BSONError("corrupted array bson"); + } else if (elementType === BSON_DATA_UNDEFINED) { + value = void 0; + } else if (elementType === BSON_DATA_NULL) { + value = null; + } else if (elementType === BSON_DATA_LONG) { + const dataview2 = BSONDataView.fromUint8Array(buffer2.subarray(index, index + 8)); + const lowBits = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + const highBits = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + const long = new Long(lowBits, highBits); + if (useBigInt64) { + value = dataview2.getBigInt64(0, true); + } else if (promoteLongs && promoteValues === true) { + value = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; + } else { + value = long; + } + } else if (elementType === BSON_DATA_DECIMAL128) { + const bytes = ByteUtils.allocate(16); + bytes.set(buffer2.subarray(index, index + 16), 0); + index = index + 16; + value = new Decimal128(bytes); + } else if (elementType === BSON_DATA_BINARY) { + let binarySize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + const totalBinarySize = binarySize; + const subType = buffer2[index++]; + if (binarySize < 0) + throw new BSONError("Negative binary type element size found"); + if (binarySize > buffer2.byteLength) + throw new BSONError("Binary type size larger than document size"); + if (buffer2["slice"] != null) { + if (subType === Binary.SUBTYPE_BYTE_ARRAY) { + binarySize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + if (binarySize < 0) + throw new BSONError("Negative binary type element size found for subtype 0x02"); + if (binarySize > totalBinarySize - 4) + throw new BSONError("Binary type with subtype 0x02 contains too long binary size"); + if (binarySize < totalBinarySize - 4) + throw new BSONError("Binary type with subtype 0x02 contains too short binary size"); + } + if (promoteBuffers && promoteValues) { + value = ByteUtils.toLocalBufferType(buffer2.slice(index, index + binarySize)); + } else { + value = new Binary(buffer2.slice(index, index + binarySize), subType); + if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) { + value = value.toUUID(); + } + } + } else { + const _buffer = ByteUtils.allocate(binarySize); + if (subType === Binary.SUBTYPE_BYTE_ARRAY) { + binarySize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + if (binarySize < 0) + throw new BSONError("Negative binary type element size found for subtype 0x02"); + if (binarySize > totalBinarySize - 4) + throw new BSONError("Binary type with subtype 0x02 contains too long binary size"); + if (binarySize < totalBinarySize - 4) + throw new BSONError("Binary type with subtype 0x02 contains too short binary size"); + } + for (i = 0; i < binarySize; i++) { + _buffer[i] = buffer2[index + i]; + } + if (promoteBuffers && promoteValues) { + value = _buffer; + } else { + value = new Binary(buffer2.slice(index, index + binarySize), subType); + if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) { + value = value.toUUID(); + } + } + } + index = index + binarySize; + } else if (elementType === BSON_DATA_REGEXP && bsonRegExp === false) { + i = index; + while (buffer2[i] !== 0 && i < buffer2.length) { + i++; + } + if (i >= buffer2.length) + throw new BSONError("Bad BSON Document: illegal CString"); + const source = ByteUtils.toUTF8(buffer2, index, i, false); + index = i + 1; + i = index; + while (buffer2[i] !== 0 && i < buffer2.length) { + i++; + } + if (i >= buffer2.length) + throw new BSONError("Bad BSON Document: illegal CString"); + const regExpOptions = ByteUtils.toUTF8(buffer2, index, i, false); + index = i + 1; + const optionsArray = new Array(regExpOptions.length); + for (i = 0; i < regExpOptions.length; i++) { + switch (regExpOptions[i]) { + case "m": + optionsArray[i] = "m"; + break; + case "s": + optionsArray[i] = "g"; + break; + case "i": + optionsArray[i] = "i"; + break; + } + } + value = new RegExp(source, optionsArray.join("")); + } else if (elementType === BSON_DATA_REGEXP && bsonRegExp === true) { + i = index; + while (buffer2[i] !== 0 && i < buffer2.length) { + i++; + } + if (i >= buffer2.length) + throw new BSONError("Bad BSON Document: illegal CString"); + const source = ByteUtils.toUTF8(buffer2, index, i, false); + index = i + 1; + i = index; + while (buffer2[i] !== 0 && i < buffer2.length) { + i++; + } + if (i >= buffer2.length) + throw new BSONError("Bad BSON Document: illegal CString"); + const regExpOptions = ByteUtils.toUTF8(buffer2, index, i, false); + index = i + 1; + value = new BSONRegExp(source, regExpOptions); + } else if (elementType === BSON_DATA_SYMBOL) { + const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) { + throw new BSONError("bad string length in bson"); + } + const symbol = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, shouldValidateKey); + value = promoteValues ? symbol : new BSONSymbol(symbol); + index = index + stringSize; + } else if (elementType === BSON_DATA_TIMESTAMP) { + const i2 = buffer2[index++] + buffer2[index++] * (1 << 8) + buffer2[index++] * (1 << 16) + buffer2[index++] * (1 << 24); + const t = buffer2[index++] + buffer2[index++] * (1 << 8) + buffer2[index++] * (1 << 16) + buffer2[index++] * (1 << 24); + value = new Timestamp({ i: i2, t }); + } else if (elementType === BSON_DATA_MIN_KEY) { + value = new MinKey(); + } else if (elementType === BSON_DATA_MAX_KEY) { + value = new MaxKey(); + } else if (elementType === BSON_DATA_CODE) { + const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) { + throw new BSONError("bad string length in bson"); + } + const functionString = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, shouldValidateKey); + value = new Code(functionString); + index = index + stringSize; + } else if (elementType === BSON_DATA_CODE_W_SCOPE) { + const totalSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + if (totalSize < 4 + 4 + 4 + 1) { + throw new BSONError("code_w_scope total size shorter minimum expected length"); + } + const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) { + throw new BSONError("bad string length in bson"); + } + const functionString = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, shouldValidateKey); + index = index + stringSize; + const _index = index; + const objectSize = buffer2[index] | buffer2[index + 1] << 8 | buffer2[index + 2] << 16 | buffer2[index + 3] << 24; + const scopeObject = deserializeObject(buffer2, _index, options, false); + index = index + objectSize; + if (totalSize < 4 + 4 + objectSize + stringSize) { + throw new BSONError("code_w_scope total size is too short, truncating scope"); + } + if (totalSize > 4 + 4 + objectSize + stringSize) { + throw new BSONError("code_w_scope total size is too long, clips outer document"); + } + value = new Code(functionString, scopeObject); + } else if (elementType === BSON_DATA_DBPOINTER) { + const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; + if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) + throw new BSONError("bad string length in bson"); + if (validation != null && validation.utf8) { + if (!validateUtf8(buffer2, index, index + stringSize - 1)) { + throw new BSONError("Invalid UTF-8 string in BSON document"); + } + } + const namespace = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, false); + index = index + stringSize; + const oidBuffer = ByteUtils.allocate(12); + oidBuffer.set(buffer2.subarray(index, index + 12), 0); + const oid = new ObjectId(oidBuffer); + index = index + 12; + value = new DBRef(namespace, oid); + } else { + throw new BSONError(`Detected unknown BSON type ${elementType.toString(16)} for fieldname "${name}"`); + } + if (name === "__proto__") { + Object.defineProperty(object, name, { + value, + writable: true, + enumerable: true, + configurable: true + }); + } else { + object[name] = value; + } + } + if (size !== index - startIndex) { + if (isArray) + throw new BSONError("corrupt array bson"); + throw new BSONError("corrupt object bson"); + } + if (!isPossibleDBRef) + return object; + if (isDBRefLike(object)) { + const copy = Object.assign({}, object); + delete copy.$ref; + delete copy.$id; + delete copy.$db; + return new DBRef(object.$ref, object.$id, object.$db, copy); + } + return object; + } + var regexp = /\x00/; + var ignoreKeys = /* @__PURE__ */ new Set(["$db", "$ref", "$id", "$clusterTime"]); + function serializeString(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_STRING; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes + 1; + buffer2[index - 1] = 0; + const size = ByteUtils.encodeUTF8Into(buffer2, value, index + 4); + buffer2[index + 3] = size + 1 >> 24 & 255; + buffer2[index + 2] = size + 1 >> 16 & 255; + buffer2[index + 1] = size + 1 >> 8 & 255; + buffer2[index] = size + 1 & 255; + index = index + 4 + size; + buffer2[index++] = 0; + return index; + } + var NUMBER_SPACE = new DataView(new ArrayBuffer(8), 0, 8); + var FOUR_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 4); + var EIGHT_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 8); + function serializeNumber(buffer2, key, value, index) { + const isNegativeZero = Object.is(value, -0); + const type = !isNegativeZero && Number.isSafeInteger(value) && value <= BSON_INT32_MAX && value >= BSON_INT32_MIN ? BSON_DATA_INT : BSON_DATA_NUMBER; + if (type === BSON_DATA_INT) { + NUMBER_SPACE.setInt32(0, value, true); + } else { + NUMBER_SPACE.setFloat64(0, value, true); + } + const bytes = type === BSON_DATA_INT ? FOUR_BYTE_VIEW_ON_NUMBER : EIGHT_BYTE_VIEW_ON_NUMBER; + buffer2[index++] = type; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + buffer2.set(bytes, index); + index += bytes.byteLength; + return index; + } + function serializeBigInt(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_LONG; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index += numberOfWrittenBytes; + buffer2[index++] = 0; + NUMBER_SPACE.setBigInt64(0, value, true); + buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER, index); + index += EIGHT_BYTE_VIEW_ON_NUMBER.byteLength; + return index; + } + function serializeNull(buffer2, key, _, index) { + buffer2[index++] = BSON_DATA_NULL; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + return index; + } + function serializeBoolean(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_BOOLEAN; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + buffer2[index++] = value ? 1 : 0; + return index; + } + function serializeDate(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_DATE; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + const dateInMilis = Long.fromNumber(value.getTime()); + const lowBits = dateInMilis.getLowBits(); + const highBits = dateInMilis.getHighBits(); + buffer2[index++] = lowBits & 255; + buffer2[index++] = lowBits >> 8 & 255; + buffer2[index++] = lowBits >> 16 & 255; + buffer2[index++] = lowBits >> 24 & 255; + buffer2[index++] = highBits & 255; + buffer2[index++] = highBits >> 8 & 255; + buffer2[index++] = highBits >> 16 & 255; + buffer2[index++] = highBits >> 24 & 255; + return index; + } + function serializeRegExp(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_REGEXP; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + if (value.source && value.source.match(regexp) != null) { + throw new BSONError("value " + value.source + " must not contain null bytes"); + } + index = index + ByteUtils.encodeUTF8Into(buffer2, value.source, index); + buffer2[index++] = 0; + if (value.ignoreCase) + buffer2[index++] = 105; + if (value.global) + buffer2[index++] = 115; + if (value.multiline) + buffer2[index++] = 109; + buffer2[index++] = 0; + return index; + } + function serializeBSONRegExp(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_REGEXP; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + if (value.pattern.match(regexp) != null) { + throw new BSONError("pattern " + value.pattern + " must not contain null bytes"); + } + index = index + ByteUtils.encodeUTF8Into(buffer2, value.pattern, index); + buffer2[index++] = 0; + const sortedOptions = value.options.split("").sort().join(""); + index = index + ByteUtils.encodeUTF8Into(buffer2, sortedOptions, index); + buffer2[index++] = 0; + return index; + } + function serializeMinMax(buffer2, key, value, index) { + if (value === null) { + buffer2[index++] = BSON_DATA_NULL; + } else if (value._bsontype === "MinKey") { + buffer2[index++] = BSON_DATA_MIN_KEY; + } else { + buffer2[index++] = BSON_DATA_MAX_KEY; + } + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + return index; + } + function serializeObjectId(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_OID; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + const idValue = value.id; + if (isUint8Array(idValue)) { + for (let i = 0; i < 12; i++) { + buffer2[index++] = idValue[i]; + } + } else { + throw new BSONError("object [" + JSON.stringify(value) + "] is not a valid ObjectId"); + } + return index; + } + function serializeBuffer(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_BINARY; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + const size = value.length; + buffer2[index++] = size & 255; + buffer2[index++] = size >> 8 & 255; + buffer2[index++] = size >> 16 & 255; + buffer2[index++] = size >> 24 & 255; + buffer2[index++] = BSON_BINARY_SUBTYPE_DEFAULT; + buffer2.set(value, index); + index = index + size; + return index; + } + function serializeObject(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path) { + if (path.has(value)) { + throw new BSONError("Cannot convert circular structure to BSON"); + } + path.add(value); + buffer2[index++] = Array.isArray(value) ? BSON_DATA_ARRAY : BSON_DATA_OBJECT; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + const endIndex = serializeInto(buffer2, value, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path); + path.delete(value); + return endIndex; + } + function serializeDecimal128(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_DECIMAL128; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + buffer2.set(value.bytes.subarray(0, 16), index); + return index + 16; + } + function serializeLong(buffer2, key, value, index) { + buffer2[index++] = value._bsontype === "Long" ? BSON_DATA_LONG : BSON_DATA_TIMESTAMP; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + const lowBits = value.getLowBits(); + const highBits = value.getHighBits(); + buffer2[index++] = lowBits & 255; + buffer2[index++] = lowBits >> 8 & 255; + buffer2[index++] = lowBits >> 16 & 255; + buffer2[index++] = lowBits >> 24 & 255; + buffer2[index++] = highBits & 255; + buffer2[index++] = highBits >> 8 & 255; + buffer2[index++] = highBits >> 16 & 255; + buffer2[index++] = highBits >> 24 & 255; + return index; + } + function serializeInt32(buffer2, key, value, index) { + value = value.valueOf(); + buffer2[index++] = BSON_DATA_INT; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + buffer2[index++] = value & 255; + buffer2[index++] = value >> 8 & 255; + buffer2[index++] = value >> 16 & 255; + buffer2[index++] = value >> 24 & 255; + return index; + } + function serializeDouble(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_NUMBER; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + NUMBER_SPACE.setFloat64(0, value.value, true); + buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER, index); + index = index + 8; + return index; + } + function serializeFunction(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_CODE; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + const functionString = value.toString(); + const size = ByteUtils.encodeUTF8Into(buffer2, functionString, index + 4) + 1; + buffer2[index] = size & 255; + buffer2[index + 1] = size >> 8 & 255; + buffer2[index + 2] = size >> 16 & 255; + buffer2[index + 3] = size >> 24 & 255; + index = index + 4 + size - 1; + buffer2[index++] = 0; + return index; + } + function serializeCode(buffer2, key, value, index, checkKeys = false, depth = 0, serializeFunctions = false, ignoreUndefined = true, path) { + if (value.scope && typeof value.scope === "object") { + buffer2[index++] = BSON_DATA_CODE_W_SCOPE; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + let startIndex = index; + const functionString = value.code; + index = index + 4; + const codeSize = ByteUtils.encodeUTF8Into(buffer2, functionString, index + 4) + 1; + buffer2[index] = codeSize & 255; + buffer2[index + 1] = codeSize >> 8 & 255; + buffer2[index + 2] = codeSize >> 16 & 255; + buffer2[index + 3] = codeSize >> 24 & 255; + buffer2[index + 4 + codeSize - 1] = 0; + index = index + codeSize + 4; + const endIndex = serializeInto(buffer2, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path); + index = endIndex - 1; + const totalSize = endIndex - startIndex; + buffer2[startIndex++] = totalSize & 255; + buffer2[startIndex++] = totalSize >> 8 & 255; + buffer2[startIndex++] = totalSize >> 16 & 255; + buffer2[startIndex++] = totalSize >> 24 & 255; + buffer2[index++] = 0; + } else { + buffer2[index++] = BSON_DATA_CODE; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + const functionString = value.code.toString(); + const size = ByteUtils.encodeUTF8Into(buffer2, functionString, index + 4) + 1; + buffer2[index] = size & 255; + buffer2[index + 1] = size >> 8 & 255; + buffer2[index + 2] = size >> 16 & 255; + buffer2[index + 3] = size >> 24 & 255; + index = index + 4 + size - 1; + buffer2[index++] = 0; + } + return index; + } + function serializeBinary(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_BINARY; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + const data = value.buffer; + let size = value.position; + if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) + size = size + 4; + buffer2[index++] = size & 255; + buffer2[index++] = size >> 8 & 255; + buffer2[index++] = size >> 16 & 255; + buffer2[index++] = size >> 24 & 255; + buffer2[index++] = value.sub_type; + if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) { + size = size - 4; + buffer2[index++] = size & 255; + buffer2[index++] = size >> 8 & 255; + buffer2[index++] = size >> 16 & 255; + buffer2[index++] = size >> 24 & 255; + } + buffer2.set(data, index); + index = index + value.position; + return index; + } + function serializeSymbol(buffer2, key, value, index) { + buffer2[index++] = BSON_DATA_SYMBOL; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + const size = ByteUtils.encodeUTF8Into(buffer2, value.value, index + 4) + 1; + buffer2[index] = size & 255; + buffer2[index + 1] = size >> 8 & 255; + buffer2[index + 2] = size >> 16 & 255; + buffer2[index + 3] = size >> 24 & 255; + index = index + 4 + size - 1; + buffer2[index++] = 0; + return index; + } + function serializeDBRef(buffer2, key, value, index, depth, serializeFunctions, path) { + buffer2[index++] = BSON_DATA_OBJECT; + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); + index = index + numberOfWrittenBytes; + buffer2[index++] = 0; + let startIndex = index; + let output = { + $ref: value.collection || value.namespace, + $id: value.oid + }; + if (value.db != null) { + output.$db = value.db; + } + output = Object.assign(output, value.fields); + const endIndex = serializeInto(buffer2, output, false, index, depth + 1, serializeFunctions, true, path); + const size = endIndex - startIndex; + buffer2[startIndex++] = size & 255; + buffer2[startIndex++] = size >> 8 & 255; + buffer2[startIndex++] = size >> 16 & 255; + buffer2[startIndex++] = size >> 24 & 255; + return endIndex; + } + function serializeInto(buffer2, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) { + if (path == null) { + if (object == null) { + buffer2[0] = 5; + buffer2[1] = 0; + buffer2[2] = 0; + buffer2[3] = 0; + buffer2[4] = 0; + return 5; + } + if (Array.isArray(object)) { + throw new BSONError("serialize does not support an array as the root input"); + } + if (typeof object !== "object") { + throw new BSONError("serialize does not support non-object as the root input"); + } else if ("_bsontype" in object && typeof object._bsontype === "string") { + throw new BSONError(`BSON types cannot be serialized as a document`); + } else if (isDate(object) || isRegExp(object) || isUint8Array(object) || isAnyArrayBuffer(object)) { + throw new BSONError(`date, regexp, typedarray, and arraybuffer cannot be BSON documents`); + } + path = /* @__PURE__ */ new Set(); + } + path.add(object); + let index = startingIndex + 4; + if (Array.isArray(object)) { + for (let i = 0; i < object.length; i++) { + const key = `${i}`; + let value = object[i]; + if (typeof value?.toBSON === "function") { + value = value.toBSON(); + } + if (typeof value === "string") { + index = serializeString(buffer2, key, value, index); + } else if (typeof value === "number") { + index = serializeNumber(buffer2, key, value, index); + } else if (typeof value === "bigint") { + index = serializeBigInt(buffer2, key, value, index); + } else if (typeof value === "boolean") { + index = serializeBoolean(buffer2, key, value, index); + } else if (value instanceof Date || isDate(value)) { + index = serializeDate(buffer2, key, value, index); + } else if (value === void 0) { + index = serializeNull(buffer2, key, value, index); + } else if (value === null) { + index = serializeNull(buffer2, key, value, index); + } else if (isUint8Array(value)) { + index = serializeBuffer(buffer2, key, value, index); + } else if (value instanceof RegExp || isRegExp(value)) { + index = serializeRegExp(buffer2, key, value, index); + } else if (typeof value === "object" && value._bsontype == null) { + index = serializeObject(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); + } else if (typeof value === "object" && value[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { + throw new BSONVersionError(); + } else if (value._bsontype === "ObjectId") { + index = serializeObjectId(buffer2, key, value, index); + } else if (value._bsontype === "Decimal128") { + index = serializeDecimal128(buffer2, key, value, index); + } else if (value._bsontype === "Long" || value._bsontype === "Timestamp") { + index = serializeLong(buffer2, key, value, index); + } else if (value._bsontype === "Double") { + index = serializeDouble(buffer2, key, value, index); + } else if (typeof value === "function" && serializeFunctions) { + index = serializeFunction(buffer2, key, value, index); + } else if (value._bsontype === "Code") { + index = serializeCode(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); + } else if (value._bsontype === "Binary") { + index = serializeBinary(buffer2, key, value, index); + } else if (value._bsontype === "BSONSymbol") { + index = serializeSymbol(buffer2, key, value, index); + } else if (value._bsontype === "DBRef") { + index = serializeDBRef(buffer2, key, value, index, depth, serializeFunctions, path); + } else if (value._bsontype === "BSONRegExp") { + index = serializeBSONRegExp(buffer2, key, value, index); + } else if (value._bsontype === "Int32") { + index = serializeInt32(buffer2, key, value, index); + } else if (value._bsontype === "MinKey" || value._bsontype === "MaxKey") { + index = serializeMinMax(buffer2, key, value, index); + } else if (typeof value._bsontype !== "undefined") { + throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); + } + } + } else if (object instanceof Map || isMap(object)) { + const iterator = object.entries(); + let done = false; + while (!done) { + const entry = iterator.next(); + done = !!entry.done; + if (done) + continue; + const key = entry.value[0]; + let value = entry.value[1]; + if (typeof value?.toBSON === "function") { + value = value.toBSON(); + } + const type = typeof value; + if (typeof key === "string" && !ignoreKeys.has(key)) { + if (key.match(regexp) != null) { + throw new BSONError("key " + key + " must not contain null bytes"); + } + if (checkKeys) { + if ("$" === key[0]) { + throw new BSONError("key " + key + " must not start with '$'"); + } else if (~key.indexOf(".")) { + throw new BSONError("key " + key + " must not contain '.'"); + } + } + } + if (type === "string") { + index = serializeString(buffer2, key, value, index); + } else if (type === "number") { + index = serializeNumber(buffer2, key, value, index); + } else if (type === "bigint") { + index = serializeBigInt(buffer2, key, value, index); + } else if (type === "boolean") { + index = serializeBoolean(buffer2, key, value, index); + } else if (value instanceof Date || isDate(value)) { + index = serializeDate(buffer2, key, value, index); + } else if (value === null || value === void 0 && ignoreUndefined === false) { + index = serializeNull(buffer2, key, value, index); + } else if (isUint8Array(value)) { + index = serializeBuffer(buffer2, key, value, index); + } else if (value instanceof RegExp || isRegExp(value)) { + index = serializeRegExp(buffer2, key, value, index); + } else if (type === "object" && value._bsontype == null) { + index = serializeObject(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); + } else if (typeof value === "object" && value[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { + throw new BSONVersionError(); + } else if (value._bsontype === "ObjectId") { + index = serializeObjectId(buffer2, key, value, index); + } else if (type === "object" && value._bsontype === "Decimal128") { + index = serializeDecimal128(buffer2, key, value, index); + } else if (value._bsontype === "Long" || value._bsontype === "Timestamp") { + index = serializeLong(buffer2, key, value, index); + } else if (value._bsontype === "Double") { + index = serializeDouble(buffer2, key, value, index); + } else if (value._bsontype === "Code") { + index = serializeCode(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); + } else if (typeof value === "function" && serializeFunctions) { + index = serializeFunction(buffer2, key, value, index); + } else if (value._bsontype === "Binary") { + index = serializeBinary(buffer2, key, value, index); + } else if (value._bsontype === "BSONSymbol") { + index = serializeSymbol(buffer2, key, value, index); + } else if (value._bsontype === "DBRef") { + index = serializeDBRef(buffer2, key, value, index, depth, serializeFunctions, path); + } else if (value._bsontype === "BSONRegExp") { + index = serializeBSONRegExp(buffer2, key, value, index); + } else if (value._bsontype === "Int32") { + index = serializeInt32(buffer2, key, value, index); + } else if (value._bsontype === "MinKey" || value._bsontype === "MaxKey") { + index = serializeMinMax(buffer2, key, value, index); + } else if (typeof value._bsontype !== "undefined") { + throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); + } + } + } else { + if (typeof object?.toBSON === "function") { + object = object.toBSON(); + if (object != null && typeof object !== "object") { + throw new BSONError("toBSON function did not return an object"); + } + } + for (const key of Object.keys(object)) { + let value = object[key]; + if (typeof value?.toBSON === "function") { + value = value.toBSON(); + } + const type = typeof value; + if (typeof key === "string" && !ignoreKeys.has(key)) { + if (key.match(regexp) != null) { + throw new BSONError("key " + key + " must not contain null bytes"); + } + if (checkKeys) { + if ("$" === key[0]) { + throw new BSONError("key " + key + " must not start with '$'"); + } else if (~key.indexOf(".")) { + throw new BSONError("key " + key + " must not contain '.'"); + } + } + } + if (type === "string") { + index = serializeString(buffer2, key, value, index); + } else if (type === "number") { + index = serializeNumber(buffer2, key, value, index); + } else if (type === "bigint") { + index = serializeBigInt(buffer2, key, value, index); + } else if (type === "boolean") { + index = serializeBoolean(buffer2, key, value, index); + } else if (value instanceof Date || isDate(value)) { + index = serializeDate(buffer2, key, value, index); + } else if (value === void 0) { + if (ignoreUndefined === false) + index = serializeNull(buffer2, key, value, index); + } else if (value === null) { + index = serializeNull(buffer2, key, value, index); + } else if (isUint8Array(value)) { + index = serializeBuffer(buffer2, key, value, index); + } else if (value instanceof RegExp || isRegExp(value)) { + index = serializeRegExp(buffer2, key, value, index); + } else if (type === "object" && value._bsontype == null) { + index = serializeObject(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); + } else if (typeof value === "object" && value[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { + throw new BSONVersionError(); + } else if (value._bsontype === "ObjectId") { + index = serializeObjectId(buffer2, key, value, index); + } else if (type === "object" && value._bsontype === "Decimal128") { + index = serializeDecimal128(buffer2, key, value, index); + } else if (value._bsontype === "Long" || value._bsontype === "Timestamp") { + index = serializeLong(buffer2, key, value, index); + } else if (value._bsontype === "Double") { + index = serializeDouble(buffer2, key, value, index); + } else if (value._bsontype === "Code") { + index = serializeCode(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); + } else if (typeof value === "function" && serializeFunctions) { + index = serializeFunction(buffer2, key, value, index); + } else if (value._bsontype === "Binary") { + index = serializeBinary(buffer2, key, value, index); + } else if (value._bsontype === "BSONSymbol") { + index = serializeSymbol(buffer2, key, value, index); + } else if (value._bsontype === "DBRef") { + index = serializeDBRef(buffer2, key, value, index, depth, serializeFunctions, path); + } else if (value._bsontype === "BSONRegExp") { + index = serializeBSONRegExp(buffer2, key, value, index); + } else if (value._bsontype === "Int32") { + index = serializeInt32(buffer2, key, value, index); + } else if (value._bsontype === "MinKey" || value._bsontype === "MaxKey") { + index = serializeMinMax(buffer2, key, value, index); + } else if (typeof value._bsontype !== "undefined") { + throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); + } + } + } + path.delete(object); + buffer2[index++] = 0; + const size = index - startingIndex; + buffer2[startingIndex++] = size & 255; + buffer2[startingIndex++] = size >> 8 & 255; + buffer2[startingIndex++] = size >> 16 & 255; + buffer2[startingIndex++] = size >> 24 & 255; + return index; + } + function isBSONType(value) { + return value != null && typeof value === "object" && "_bsontype" in value && typeof value._bsontype === "string"; + } + var keysToCodecs = { + $oid: ObjectId, + $binary: Binary, + $uuid: Binary, + $symbol: BSONSymbol, + $numberInt: Int32, + $numberDecimal: Decimal128, + $numberDouble: Double, + $numberLong: Long, + $minKey: MinKey, + $maxKey: MaxKey, + $regex: BSONRegExp, + $regularExpression: BSONRegExp, + $timestamp: Timestamp + }; + function deserializeValue(value, options = {}) { + if (typeof value === "number") { + const in32BitRange = value <= BSON_INT32_MAX && value >= BSON_INT32_MIN; + const in64BitRange = value <= BSON_INT64_MAX && value >= BSON_INT64_MIN; + if (options.relaxed || options.legacy) { + return value; + } + if (Number.isInteger(value) && !Object.is(value, -0)) { + if (in32BitRange) { + return new Int32(value); + } + if (in64BitRange) { + if (options.useBigInt64) { + return BigInt(value); + } + return Long.fromNumber(value); + } + } + return new Double(value); + } + if (value == null || typeof value !== "object") + return value; + if (value.$undefined) + return null; + const keys = Object.keys(value).filter((k) => k.startsWith("$") && value[k] != null); + for (let i = 0; i < keys.length; i++) { + const c = keysToCodecs[keys[i]]; + if (c) + return c.fromExtendedJSON(value, options); + } + if (value.$date != null) { + const d = value.$date; + const date = /* @__PURE__ */ new Date(); + if (options.legacy) { + if (typeof d === "number") + date.setTime(d); + else if (typeof d === "string") + date.setTime(Date.parse(d)); + else if (typeof d === "bigint") + date.setTime(Number(d)); + else + throw new BSONRuntimeError(`Unrecognized type for EJSON date: ${typeof d}`); + } else { + if (typeof d === "string") + date.setTime(Date.parse(d)); + else if (Long.isLong(d)) + date.setTime(d.toNumber()); + else if (typeof d === "number" && options.relaxed) + date.setTime(d); + else if (typeof d === "bigint") + date.setTime(Number(d)); + else + throw new BSONRuntimeError(`Unrecognized type for EJSON date: ${typeof d}`); + } + return date; + } + if (value.$code != null) { + const copy = Object.assign({}, value); + if (value.$scope) { + copy.$scope = deserializeValue(value.$scope); + } + return Code.fromExtendedJSON(value); + } + if (isDBRefLike(value) || value.$dbPointer) { + const v = value.$ref ? value : value.$dbPointer; + if (v instanceof DBRef) + return v; + const dollarKeys = Object.keys(v).filter((k) => k.startsWith("$")); + let valid = true; + dollarKeys.forEach((k) => { + if (["$ref", "$id", "$db"].indexOf(k) === -1) + valid = false; + }); + if (valid) + return DBRef.fromExtendedJSON(v); + } + return value; + } + function serializeArray(array, options) { + return array.map((v, index) => { + options.seenObjects.push({ propertyName: `index ${index}`, obj: null }); + try { + return serializeValue(v, options); + } finally { + options.seenObjects.pop(); + } + }); + } + function getISOString(date) { + const isoStr = date.toISOString(); + return date.getUTCMilliseconds() !== 0 ? isoStr : isoStr.slice(0, -5) + "Z"; + } + function serializeValue(value, options) { + if (value instanceof Map || isMap(value)) { + const obj = /* @__PURE__ */ Object.create(null); + for (const [k, v] of value) { + if (typeof k !== "string") { + throw new BSONError("Can only serialize maps with string keys"); + } + obj[k] = v; + } + return serializeValue(obj, options); + } + if ((typeof value === "object" || typeof value === "function") && value !== null) { + const index = options.seenObjects.findIndex((entry) => entry.obj === value); + if (index !== -1) { + const props = options.seenObjects.map((entry) => entry.propertyName); + const leadingPart = props.slice(0, index).map((prop) => `${prop} -> `).join(""); + const alreadySeen = props[index]; + const circularPart = " -> " + props.slice(index + 1, props.length - 1).map((prop) => `${prop} -> `).join(""); + const current = props[props.length - 1]; + const leadingSpace = " ".repeat(leadingPart.length + alreadySeen.length / 2); + const dashes = "-".repeat(circularPart.length + (alreadySeen.length + current.length) / 2 - 1); + throw new BSONError(`Converting circular structure to EJSON: + ${leadingPart}${alreadySeen}${circularPart}${current} + ${leadingSpace}\\${dashes}/`); + } + options.seenObjects[options.seenObjects.length - 1].obj = value; + } + if (Array.isArray(value)) + return serializeArray(value, options); + if (value === void 0) + return null; + if (value instanceof Date || isDate(value)) { + const dateNum = value.getTime(), inRange = dateNum > -1 && dateNum < 2534023188e5; + if (options.legacy) { + return options.relaxed && inRange ? { $date: value.getTime() } : { $date: getISOString(value) }; + } + return options.relaxed && inRange ? { $date: getISOString(value) } : { $date: { $numberLong: value.getTime().toString() } }; + } + if (typeof value === "number" && (!options.relaxed || !isFinite(value))) { + if (Number.isInteger(value) && !Object.is(value, -0)) { + if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) { + return { $numberInt: value.toString() }; + } + if (value >= BSON_INT64_MIN && value <= BSON_INT64_MAX) { + return { $numberLong: value.toString() }; + } + } + return { $numberDouble: Object.is(value, -0) ? "-0.0" : value.toString() }; + } + if (typeof value === "bigint") { + if (!options.relaxed) { + return { $numberLong: BigInt.asIntN(64, value).toString() }; + } + return Number(BigInt.asIntN(64, value)); + } + if (value instanceof RegExp || isRegExp(value)) { + let flags = value.flags; + if (flags === void 0) { + const match = value.toString().match(/[gimuy]*$/); + if (match) { + flags = match[0]; + } + } + const rx = new BSONRegExp(value.source, flags); + return rx.toExtendedJSON(options); + } + if (value != null && typeof value === "object") + return serializeDocument(value, options); + return value; + } + var BSON_TYPE_MAPPINGS = { + Binary: (o) => new Binary(o.value(), o.sub_type), + Code: (o) => new Code(o.code, o.scope), + DBRef: (o) => new DBRef(o.collection || o.namespace, o.oid, o.db, o.fields), + Decimal128: (o) => new Decimal128(o.bytes), + Double: (o) => new Double(o.value), + Int32: (o) => new Int32(o.value), + Long: (o) => Long.fromBits(o.low != null ? o.low : o.low_, o.low != null ? o.high : o.high_, o.low != null ? o.unsigned : o.unsigned_), + MaxKey: () => new MaxKey(), + MinKey: () => new MinKey(), + ObjectId: (o) => new ObjectId(o), + BSONRegExp: (o) => new BSONRegExp(o.pattern, o.options), + BSONSymbol: (o) => new BSONSymbol(o.value), + Timestamp: (o) => Timestamp.fromBits(o.low, o.high) + }; + function serializeDocument(doc, options) { + if (doc == null || typeof doc !== "object") + throw new BSONError("not an object instance"); + const bsontype = doc._bsontype; + if (typeof bsontype === "undefined") { + const _doc = {}; + for (const name of Object.keys(doc)) { + options.seenObjects.push({ propertyName: name, obj: null }); + try { + const value = serializeValue(doc[name], options); + if (name === "__proto__") { + Object.defineProperty(_doc, name, { + value, + writable: true, + enumerable: true, + configurable: true + }); + } else { + _doc[name] = value; + } + } finally { + options.seenObjects.pop(); + } + } + return _doc; + } else if (doc != null && typeof doc === "object" && typeof doc._bsontype === "string" && doc[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { + throw new BSONVersionError(); + } else if (isBSONType(doc)) { + let outDoc = doc; + if (typeof outDoc.toExtendedJSON !== "function") { + const mapper = BSON_TYPE_MAPPINGS[doc._bsontype]; + if (!mapper) { + throw new BSONError("Unrecognized or invalid _bsontype: " + doc._bsontype); + } + outDoc = mapper(outDoc); + } + if (bsontype === "Code" && outDoc.scope) { + outDoc = new Code(outDoc.code, serializeValue(outDoc.scope, options)); + } else if (bsontype === "DBRef" && outDoc.oid) { + outDoc = new DBRef(serializeValue(outDoc.collection, options), serializeValue(outDoc.oid, options), serializeValue(outDoc.db, options), serializeValue(outDoc.fields, options)); + } + return outDoc.toExtendedJSON(options); + } else { + throw new BSONError("_bsontype must be a string, but was: " + typeof bsontype); + } + } + function parse(text, options) { + const ejsonOptions = { + useBigInt64: options?.useBigInt64 ?? false, + relaxed: options?.relaxed ?? true, + legacy: options?.legacy ?? false + }; + return JSON.parse(text, (key, value) => { + if (key.indexOf("\0") !== -1) { + throw new BSONError(`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(key)}`); + } + return deserializeValue(value, ejsonOptions); + }); + } + function stringify(value, replacer, space, options) { + if (space != null && typeof space === "object") { + options = space; + space = 0; + } + if (replacer != null && typeof replacer === "object" && !Array.isArray(replacer)) { + options = replacer; + replacer = void 0; + space = 0; + } + const serializeOptions = Object.assign({ relaxed: true, legacy: false }, options, { + seenObjects: [{ propertyName: "(root)", obj: null }] + }); + const doc = serializeValue(value, serializeOptions); + return JSON.stringify(doc, replacer, space); + } + function EJSONserialize(value, options) { + options = options || {}; + return JSON.parse(stringify(value, options)); + } + function EJSONdeserialize(ejson, options) { + options = options || {}; + return parse(JSON.stringify(ejson), options); + } + var EJSON = /* @__PURE__ */ Object.create(null); + EJSON.parse = parse; + EJSON.stringify = stringify; + EJSON.serialize = EJSONserialize; + EJSON.deserialize = EJSONdeserialize; + Object.freeze(EJSON); + var MAXSIZE = 1024 * 1024 * 17; + var buffer = ByteUtils.allocate(MAXSIZE); + function setInternalBufferSize(size) { + if (buffer.length < size) { + buffer = ByteUtils.allocate(size); + } + } + function serialize(object, options = {}) { + const checkKeys = typeof options.checkKeys === "boolean" ? options.checkKeys : false; + const serializeFunctions = typeof options.serializeFunctions === "boolean" ? options.serializeFunctions : false; + const ignoreUndefined = typeof options.ignoreUndefined === "boolean" ? options.ignoreUndefined : true; + const minInternalBufferSize = typeof options.minInternalBufferSize === "number" ? options.minInternalBufferSize : MAXSIZE; + if (buffer.length < minInternalBufferSize) { + buffer = ByteUtils.allocate(minInternalBufferSize); + } + const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null); + const finishedBuffer = ByteUtils.allocate(serializationIndex); + finishedBuffer.set(buffer.subarray(0, serializationIndex), 0); + return finishedBuffer; + } + function serializeWithBufferAndIndex(object, finalBuffer, options = {}) { + const checkKeys = typeof options.checkKeys === "boolean" ? options.checkKeys : false; + const serializeFunctions = typeof options.serializeFunctions === "boolean" ? options.serializeFunctions : false; + const ignoreUndefined = typeof options.ignoreUndefined === "boolean" ? options.ignoreUndefined : true; + const startIndex = typeof options.index === "number" ? options.index : 0; + const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null); + finalBuffer.set(buffer.subarray(0, serializationIndex), startIndex); + return startIndex + serializationIndex - 1; + } + function deserialize(buffer2, options = {}) { + return internalDeserialize(ByteUtils.toLocalBufferType(buffer2), options); + } + function calculateObjectSize(object, options = {}) { + options = options || {}; + const serializeFunctions = typeof options.serializeFunctions === "boolean" ? options.serializeFunctions : false; + const ignoreUndefined = typeof options.ignoreUndefined === "boolean" ? options.ignoreUndefined : true; + return internalCalculateObjectSize(object, serializeFunctions, ignoreUndefined); + } + function deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { + const internalOptions = Object.assign({ allowObjectSmallerThanBufferSize: true, index: 0 }, options); + const bufferData = ByteUtils.toLocalBufferType(data); + let index = startIndex; + for (let i = 0; i < numberOfDocuments; i++) { + const size = bufferData[index] | bufferData[index + 1] << 8 | bufferData[index + 2] << 16 | bufferData[index + 3] << 24; + internalOptions.index = index; + documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions); + index = index + size; + } + return index; + } + var bson2 = /* @__PURE__ */ Object.freeze({ + __proto__: null, + BSONError, + BSONRegExp, + BSONRuntimeError, + BSONSymbol, + BSONType, + BSONValue, + BSONVersionError, + Binary, + Code, + DBRef, + Decimal128, + Double, + EJSON, + Int32, + Long, + MaxKey, + MinKey, + ObjectId, + Timestamp, + UUID, + calculateObjectSize, + deserialize, + deserializeStream, + serialize, + serializeWithBufferAndIndex, + setInternalBufferSize + }); + exports.BSON = bson2; + exports.BSONError = BSONError; + exports.BSONRegExp = BSONRegExp; + exports.BSONRuntimeError = BSONRuntimeError; + exports.BSONSymbol = BSONSymbol; + exports.BSONType = BSONType; + exports.BSONValue = BSONValue; + exports.BSONVersionError = BSONVersionError; + exports.Binary = Binary; + exports.Code = Code; + exports.DBRef = DBRef; + exports.Decimal128 = Decimal128; + exports.Double = Double; + exports.EJSON = EJSON; + exports.Int32 = Int32; + exports.Long = Long; + exports.MaxKey = MaxKey; + exports.MinKey = MinKey; + exports.ObjectId = ObjectId; + exports.Timestamp = Timestamp; + exports.UUID = UUID; + exports.calculateObjectSize = calculateObjectSize; + exports.deserialize = deserialize; + exports.deserializeStream = deserializeStream; + exports.serialize = serialize; + exports.serializeWithBufferAndIndex = serializeWithBufferAndIndex; + exports.setInternalBufferSize = setInternalBufferSize; + } + }); + + // src/jsRunner/bundles/bsonPackage.ts + var bson = { + deserialize: require_bson().deserialize, + toJson: require_bson().EJSON.deserialize + }; + return bson +})(); diff --git a/packages/server/src/jsRunner/bundles/bsonPackage.ts b/packages/server/src/jsRunner/bundles/bsonPackage.ts index b2e9016879..fc7969f17d 100644 --- a/packages/server/src/jsRunner/bundles/bsonPackage.ts +++ b/packages/server/src/jsRunner/bundles/bsonPackage.ts @@ -1,4 +1,4 @@ -import { EJSON } from "bson" - -export { deserialize } from "bson" -export const toJson = EJSON.deserialize +export const bson = { + deserialize: require("bson").deserialize, + toJson: require("bson").EJSON.deserialize, +} diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index ac01a52a6e..1b1135e1f7 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -115,9 +115,9 @@ export class IsolatedVM implements VM { // 4. Stringify the result in order to convert the result from BSON to json this.codeWrapper = code => `(function(){ - const data = deserialize(bsonData, { validation: { utf8: false } }).data; + const data = bson.deserialize(bsonData, { validation: { utf8: false } }).data; const result = ${code} - return toJson(result); + return bson.toJson(result); })();` const bsonSource = loadBundle(BundleType.BSON) @@ -137,7 +137,7 @@ export class IsolatedVM implements VM { }) // "Polyfilling" text decoder. `bson.deserialize` requires decoding. We are creating a bridge function so we don't need to inject the full library - const textDecoderPolyfill = class TextDecoder { + const textDecoderPolyfill = class TextDecoderMock { constructorArgs constructor(...constructorArgs: any) { @@ -151,19 +151,11 @@ export class IsolatedVM implements VM { functionArgs: input, }) } - }.toString() - const bsonModule = this.isolate.compileModuleSync( - `${textDecoderPolyfill};${bsonSource}` - ) - bsonModule.instantiateSync(this.vm, specifier => { - throw new Error(`No imports allowed. Required: ${specifier}`) - }) + } + .toString() + .replace(/TextDecoderMock/, "TextDecoder") - this.moduleHandler.registerModule( - bsonModule, - "{deserialize, toJson}", - "bson" - ) + this.moduleHandler.registerModule(`${textDecoderPolyfill};${bsonSource}`) return this } @@ -178,13 +170,17 @@ export class IsolatedVM implements VM { } } - code = `${this.moduleHandler.generateImports()};${this.codeWrapper(code)};` + code = `${this.moduleHandler.generateImports()};results.out=${this.codeWrapper( + code + )}` const script = this.isolate.compileScriptSync(code) - const result = script.runSync(this.vm, { timeout: this.invocationTimeout }) + script.runSync(this.vm, { timeout: this.invocationTimeout }) - return result + // We can't rely on the script run result as it will not work for non-transferable values + const result = this.getFromContext(this.resultKey) + return result.out } private registerCallbacks(functions: Record) { @@ -220,4 +216,11 @@ export class IsolatedVM implements VM { ) } } + + private getFromContext(key: string) { + const ref = this.vm.global.getSync(key, { reference: true }) + const result = ref.copySync() + ref.release() + return result + } } From fa2fbb4253e8bdd63bc35105b555e5b472ad5b07 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 16:57:33 +0100 Subject: [PATCH 031/213] Update command --- packages/server/package.json | 4 +- .../src/jsRunner/bundles/bson.ivm.bundle.js | 42 ++++++++++++++----- .../src/jsRunner/bundles/bsonPackage.ts | 6 +-- .../bundles/index-helpers.ivm.bundle.js | 10 +++-- 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/packages/server/package.json b/packages/server/package.json index e600e36bd3..57e1a828b7 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -13,8 +13,8 @@ "build": "node ./scripts/build.js", "postbuild": "copyfiles -f ../client/dist/budibase-client.js ../client/manifest.json client && copyfiles -f ../../yarn.lock ./dist/", "check:types": "tsc -p tsconfig.json --noEmit --paths null", - "build:isolated-vm-lib:string-templates": "esbuild --minify --bundle src/jsRunner/bundles/index-helpers.ts --outfile=src/jsRunner/bundles/index-helpers.ivm.bundle.js --platform=node --format=esm --external:handlebars", - "build:isolated-vm-lib:bson": "esbuild --minify --bundle src/jsRunner/bundles/bsonPackage.ts --outfile=src/jsRunner/bundles/bson.ivm.bundle.js --platform=node --format=esm", + "build:isolated-vm-lib:string-templates": "esbuild --minify --bundle src/jsRunner/bundles/index-helpers.ts --outfile=src/jsRunner/bundles/index-helpers.ivm.bundle.js --platform=node --format=iife --external:handlebars --global-name=helpers", + "build:isolated-vm-lib:bson": "esbuild --minify --bundle src/jsRunner/bundles/bsonPackage.ts --outfile=src/jsRunner/bundles/bson.ivm.bundle.js --platform=node --format=iife --global-name=bson", "build:isolated-vm-libs": "yarn build:isolated-vm-lib:string-templates && yarn build:isolated-vm-lib:bson", "build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput", "debug": "yarn build && node --expose-gc --inspect=9222 dist/index.js", diff --git a/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js b/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js index f83c062429..96154a4036 100644 --- a/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js +++ b/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js @@ -1,5 +1,9 @@ -const bson=(() => { +"use strict"; +var bson = (() => { + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { @@ -10,6 +14,19 @@ const bson=(() => { var __commonJS = (cb, mod) => function __require2() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // ../../node_modules/bson/lib/bson.cjs var require_bson = __commonJS({ @@ -3705,7 +3722,7 @@ const bson=(() => { finalBuffer.set(buffer.subarray(0, serializationIndex), startIndex); return startIndex + serializationIndex - 1; } - function deserialize(buffer2, options = {}) { + function deserialize2(buffer2, options = {}) { return internalDeserialize(ByteUtils.toLocalBufferType(buffer2), options); } function calculateObjectSize(object, options = {}) { @@ -3726,7 +3743,7 @@ const bson=(() => { } return index; } - var bson2 = /* @__PURE__ */ Object.freeze({ + var bson = /* @__PURE__ */ Object.freeze({ __proto__: null, BSONError, BSONRegExp, @@ -3749,13 +3766,13 @@ const bson=(() => { Timestamp, UUID, calculateObjectSize, - deserialize, + deserialize: deserialize2, deserializeStream, serialize, serializeWithBufferAndIndex, setInternalBufferSize }); - exports.BSON = bson2; + exports.BSON = bson; exports.BSONError = BSONError; exports.BSONRegExp = BSONRegExp; exports.BSONRuntimeError = BSONRuntimeError; @@ -3777,7 +3794,7 @@ const bson=(() => { exports.Timestamp = Timestamp; exports.UUID = UUID; exports.calculateObjectSize = calculateObjectSize; - exports.deserialize = deserialize; + exports.deserialize = deserialize2; exports.deserializeStream = deserializeStream; exports.serialize = serialize; exports.serializeWithBufferAndIndex = serializeWithBufferAndIndex; @@ -3786,9 +3803,12 @@ const bson=(() => { }); // src/jsRunner/bundles/bsonPackage.ts - var bson = { - deserialize: require_bson().deserialize, - toJson: require_bson().EJSON.deserialize - }; - return bson + var bsonPackage_exports = {}; + __export(bsonPackage_exports, { + deserialize: () => deserialize, + toJson: () => toJson + }); + var deserialize = require_bson().deserialize; + var toJson = require_bson().EJSON.deserialize; + return __toCommonJS(bsonPackage_exports); })(); diff --git a/packages/server/src/jsRunner/bundles/bsonPackage.ts b/packages/server/src/jsRunner/bundles/bsonPackage.ts index fc7969f17d..600b18e4c8 100644 --- a/packages/server/src/jsRunner/bundles/bsonPackage.ts +++ b/packages/server/src/jsRunner/bundles/bsonPackage.ts @@ -1,4 +1,2 @@ -export const bson = { - deserialize: require("bson").deserialize, - toJson: require("bson").EJSON.deserialize, -} +export const deserialize = require("bson").deserialize +export const toJson = require("bson").EJSON.deserialize diff --git a/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js b/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js index 2201586ec0..b2e9f29892 100644 --- a/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js +++ b/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js @@ -1,4 +1,5 @@ -const helpers= (() => { +"use strict"; +var helpers = (() => { var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; @@ -3538,6 +3539,10 @@ const helpers= (() => { }); // src/jsRunner/bundles/index-helpers.ts + var index_helpers_exports = {}; + __export(index_helpers_exports, { + helpers: () => helpers + }); var { getJsHelperList } = require_list(); @@ -3548,8 +3553,7 @@ const helpers= (() => { // eslint-disable-next-line no-undef stripProtocol: helpersStripProtocol }; - - return helpers + return __toCommonJS(index_helpers_exports); })(); /*! Bundled license information: From 0bf94bcd7b2da880f12ce087fd8d16aa461565d5 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 17:16:59 +0100 Subject: [PATCH 032/213] Fix helpers --- .../src/jsRunner/bundles/bson.ivm.bundle.js | 3821 +---------------- .../bundles/index-helpers.ivm.bundle.js | 3558 +-------------- .../src/jsRunner/bundles/index-helpers.ts | 2 +- packages/server/src/jsRunner/vm/index.ts | 12 +- 4 files changed, 16 insertions(+), 7377 deletions(-) diff --git a/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js b/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js index 96154a4036..5c49ce78e6 100644 --- a/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js +++ b/packages/server/src/jsRunner/bundles/bson.ivm.bundle.js @@ -1,3814 +1,7 @@ -"use strict"; -var bson = (() => { - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { - get: (a, b) => (typeof require !== "undefined" ? require : a)[b] - }) : x)(function(x) { - if (typeof require !== "undefined") - return require.apply(this, arguments); - throw Error('Dynamic require of "' + x + '" is not supported'); - }); - var __commonJS = (cb, mod) => function __require2() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; - }; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - - // ../../node_modules/bson/lib/bson.cjs - var require_bson = __commonJS({ - "../../node_modules/bson/lib/bson.cjs"(exports) { - "use strict"; - function isAnyArrayBuffer(value) { - return ["[object ArrayBuffer]", "[object SharedArrayBuffer]"].includes(Object.prototype.toString.call(value)); - } - function isUint8Array(value) { - return Object.prototype.toString.call(value) === "[object Uint8Array]"; - } - function isRegExp(d) { - return Object.prototype.toString.call(d) === "[object RegExp]"; - } - function isMap(d) { - return Object.prototype.toString.call(d) === "[object Map]"; - } - function isDate(d) { - return Object.prototype.toString.call(d) === "[object Date]"; - } - function defaultInspect(x, _options) { - return JSON.stringify(x, (k, v) => { - if (typeof v === "bigint") { - return { $numberLong: `${v}` }; - } else if (isMap(v)) { - return Object.fromEntries(v); - } - return v; - }); - } - function getStylizeFunction(options) { - const stylizeExists = options != null && typeof options === "object" && "stylize" in options && typeof options.stylize === "function"; - if (stylizeExists) { - return options.stylize; - } - } - var BSON_MAJOR_VERSION = 6; - var BSON_INT32_MAX = 2147483647; - var BSON_INT32_MIN = -2147483648; - var BSON_INT64_MAX = Math.pow(2, 63) - 1; - var BSON_INT64_MIN = -Math.pow(2, 63); - var JS_INT_MAX = Math.pow(2, 53); - var JS_INT_MIN = -Math.pow(2, 53); - var BSON_DATA_NUMBER = 1; - var BSON_DATA_STRING = 2; - var BSON_DATA_OBJECT = 3; - var BSON_DATA_ARRAY = 4; - var BSON_DATA_BINARY = 5; - var BSON_DATA_UNDEFINED = 6; - var BSON_DATA_OID = 7; - var BSON_DATA_BOOLEAN = 8; - var BSON_DATA_DATE = 9; - var BSON_DATA_NULL = 10; - var BSON_DATA_REGEXP = 11; - var BSON_DATA_DBPOINTER = 12; - var BSON_DATA_CODE = 13; - var BSON_DATA_SYMBOL = 14; - var BSON_DATA_CODE_W_SCOPE = 15; - var BSON_DATA_INT = 16; - var BSON_DATA_TIMESTAMP = 17; - var BSON_DATA_LONG = 18; - var BSON_DATA_DECIMAL128 = 19; - var BSON_DATA_MIN_KEY = 255; - var BSON_DATA_MAX_KEY = 127; - var BSON_BINARY_SUBTYPE_DEFAULT = 0; - var BSON_BINARY_SUBTYPE_UUID_NEW = 4; - var BSONType = Object.freeze({ - double: 1, - string: 2, - object: 3, - array: 4, - binData: 5, - undefined: 6, - objectId: 7, - bool: 8, - date: 9, - null: 10, - regex: 11, - dbPointer: 12, - javascript: 13, - symbol: 14, - javascriptWithScope: 15, - int: 16, - timestamp: 17, - long: 18, - decimal: 19, - minKey: -1, - maxKey: 127 - }); - var BSONError = class extends Error { - get bsonError() { - return true; - } - get name() { - return "BSONError"; - } - constructor(message, options) { - super(message, options); - } - static isBSONError(value) { - return value != null && typeof value === "object" && "bsonError" in value && value.bsonError === true && "name" in value && "message" in value && "stack" in value; - } - }; - var BSONVersionError = class extends BSONError { - get name() { - return "BSONVersionError"; - } - constructor() { - super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.x.x`); - } - }; - var BSONRuntimeError = class extends BSONError { - get name() { - return "BSONRuntimeError"; - } - constructor(message) { - super(message); - } - }; - var FIRST_BIT = 128; - var FIRST_TWO_BITS = 192; - var FIRST_THREE_BITS = 224; - var FIRST_FOUR_BITS = 240; - var FIRST_FIVE_BITS = 248; - var TWO_BIT_CHAR = 192; - var THREE_BIT_CHAR = 224; - var FOUR_BIT_CHAR = 240; - var CONTINUING_CHAR = 128; - function validateUtf8(bytes, start, end) { - let continuation = 0; - for (let i = start; i < end; i += 1) { - const byte = bytes[i]; - if (continuation) { - if ((byte & FIRST_TWO_BITS) !== CONTINUING_CHAR) { - return false; - } - continuation -= 1; - } else if (byte & FIRST_BIT) { - if ((byte & FIRST_THREE_BITS) === TWO_BIT_CHAR) { - continuation = 1; - } else if ((byte & FIRST_FOUR_BITS) === THREE_BIT_CHAR) { - continuation = 2; - } else if ((byte & FIRST_FIVE_BITS) === FOUR_BIT_CHAR) { - continuation = 3; - } else { - return false; - } - } - } - return !continuation; - } - function tryLatin(uint8array, start, end) { - if (uint8array.length === 0) { - return ""; - } - const stringByteLength = end - start; - if (stringByteLength === 0) { - return ""; - } - if (stringByteLength > 20) { - return null; - } - if (stringByteLength === 1 && uint8array[start] < 128) { - return String.fromCharCode(uint8array[start]); - } - if (stringByteLength === 2 && uint8array[start] < 128 && uint8array[start + 1] < 128) { - return String.fromCharCode(uint8array[start]) + String.fromCharCode(uint8array[start + 1]); - } - if (stringByteLength === 3 && uint8array[start] < 128 && uint8array[start + 1] < 128 && uint8array[start + 2] < 128) { - return String.fromCharCode(uint8array[start]) + String.fromCharCode(uint8array[start + 1]) + String.fromCharCode(uint8array[start + 2]); - } - const latinBytes = []; - for (let i = start; i < end; i++) { - const byte = uint8array[i]; - if (byte > 127) { - return null; - } - latinBytes.push(byte); - } - return String.fromCharCode(...latinBytes); - } - function nodejsMathRandomBytes(byteLength) { - return nodeJsByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256))); - } - var nodejsRandomBytes = (() => { - try { - return __require("crypto").randomBytes; - } catch { - return nodejsMathRandomBytes; - } - })(); - var nodeJsByteUtils = { - toLocalBufferType(potentialBuffer) { - if (Buffer.isBuffer(potentialBuffer)) { - return potentialBuffer; - } - if (ArrayBuffer.isView(potentialBuffer)) { - return Buffer.from(potentialBuffer.buffer, potentialBuffer.byteOffset, potentialBuffer.byteLength); - } - const stringTag = potentialBuffer?.[Symbol.toStringTag] ?? Object.prototype.toString.call(potentialBuffer); - if (stringTag === "ArrayBuffer" || stringTag === "SharedArrayBuffer" || stringTag === "[object ArrayBuffer]" || stringTag === "[object SharedArrayBuffer]") { - return Buffer.from(potentialBuffer); - } - throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`); - }, - allocate(size) { - return Buffer.alloc(size); - }, - equals(a, b) { - return nodeJsByteUtils.toLocalBufferType(a).equals(b); - }, - fromNumberArray(array) { - return Buffer.from(array); - }, - fromBase64(base64) { - return Buffer.from(base64, "base64"); - }, - toBase64(buffer2) { - return nodeJsByteUtils.toLocalBufferType(buffer2).toString("base64"); - }, - fromISO88591(codePoints) { - return Buffer.from(codePoints, "binary"); - }, - toISO88591(buffer2) { - return nodeJsByteUtils.toLocalBufferType(buffer2).toString("binary"); - }, - fromHex(hex) { - return Buffer.from(hex, "hex"); - }, - toHex(buffer2) { - return nodeJsByteUtils.toLocalBufferType(buffer2).toString("hex"); - }, - fromUTF8(text) { - return Buffer.from(text, "utf8"); - }, - toUTF8(buffer2, start, end, fatal) { - const basicLatin = end - start <= 20 ? tryLatin(buffer2, start, end) : null; - if (basicLatin != null) { - return basicLatin; - } - const string = nodeJsByteUtils.toLocalBufferType(buffer2).toString("utf8", start, end); - if (fatal) { - for (let i = 0; i < string.length; i++) { - if (string.charCodeAt(i) === 65533) { - if (!validateUtf8(buffer2, start, end)) { - throw new BSONError("Invalid UTF-8 string in BSON document"); - } - break; - } - } - } - return string; - }, - utf8ByteLength(input) { - return Buffer.byteLength(input, "utf8"); - }, - encodeUTF8Into(buffer2, source, byteOffset) { - return nodeJsByteUtils.toLocalBufferType(buffer2).write(source, byteOffset, void 0, "utf8"); - }, - randomBytes: nodejsRandomBytes - }; - function isReactNative() { - const { navigator } = globalThis; - return typeof navigator === "object" && navigator.product === "ReactNative"; - } - function webMathRandomBytes(byteLength) { - if (byteLength < 0) { - throw new RangeError(`The argument 'byteLength' is invalid. Received ${byteLength}`); - } - return webByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256))); - } - var webRandomBytes = (() => { - const { crypto } = globalThis; - if (crypto != null && typeof crypto.getRandomValues === "function") { - return (byteLength) => { - return crypto.getRandomValues(webByteUtils.allocate(byteLength)); - }; - } else { - if (isReactNative()) { - const { console } = globalThis; - console?.warn?.("BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values."); - } - return webMathRandomBytes; - } - })(); - var HEX_DIGIT = /(\d|[a-f])/i; - var webByteUtils = { - toLocalBufferType(potentialUint8array) { - const stringTag = potentialUint8array?.[Symbol.toStringTag] ?? Object.prototype.toString.call(potentialUint8array); - if (stringTag === "Uint8Array") { - return potentialUint8array; - } - if (ArrayBuffer.isView(potentialUint8array)) { - return new Uint8Array(potentialUint8array.buffer.slice(potentialUint8array.byteOffset, potentialUint8array.byteOffset + potentialUint8array.byteLength)); - } - if (stringTag === "ArrayBuffer" || stringTag === "SharedArrayBuffer" || stringTag === "[object ArrayBuffer]" || stringTag === "[object SharedArrayBuffer]") { - return new Uint8Array(potentialUint8array); - } - throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`); - }, - allocate(size) { - if (typeof size !== "number") { - throw new TypeError(`The "size" argument must be of type number. Received ${String(size)}`); - } - return new Uint8Array(size); - }, - equals(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - for (let i = 0; i < a.byteLength; i++) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - }, - fromNumberArray(array) { - return Uint8Array.from(array); - }, - fromBase64(base64) { - return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)); - }, - toBase64(uint8array) { - return btoa(webByteUtils.toISO88591(uint8array)); - }, - fromISO88591(codePoints) { - return Uint8Array.from(codePoints, (c) => c.charCodeAt(0) & 255); - }, - toISO88591(uint8array) { - return Array.from(Uint16Array.from(uint8array), (b) => String.fromCharCode(b)).join(""); - }, - fromHex(hex) { - const evenLengthHex = hex.length % 2 === 0 ? hex : hex.slice(0, hex.length - 1); - const buffer2 = []; - for (let i = 0; i < evenLengthHex.length; i += 2) { - const firstDigit = evenLengthHex[i]; - const secondDigit = evenLengthHex[i + 1]; - if (!HEX_DIGIT.test(firstDigit)) { - break; - } - if (!HEX_DIGIT.test(secondDigit)) { - break; - } - const hexDigit = Number.parseInt(`${firstDigit}${secondDigit}`, 16); - buffer2.push(hexDigit); - } - return Uint8Array.from(buffer2); - }, - toHex(uint8array) { - return Array.from(uint8array, (byte) => byte.toString(16).padStart(2, "0")).join(""); - }, - fromUTF8(text) { - return new TextEncoder().encode(text); - }, - toUTF8(uint8array, start, end, fatal) { - const basicLatin = end - start <= 20 ? tryLatin(uint8array, start, end) : null; - if (basicLatin != null) { - return basicLatin; - } - if (fatal) { - try { - return new TextDecoder("utf8", { fatal }).decode(uint8array.slice(start, end)); - } catch (cause) { - throw new BSONError("Invalid UTF-8 string in BSON document", { cause }); - } - } - return new TextDecoder("utf8", { fatal }).decode(uint8array.slice(start, end)); - }, - utf8ByteLength(input) { - return webByteUtils.fromUTF8(input).byteLength; - }, - encodeUTF8Into(buffer2, source, byteOffset) { - const bytes = webByteUtils.fromUTF8(source); - buffer2.set(bytes, byteOffset); - return bytes.byteLength; - }, - randomBytes: webRandomBytes - }; - var hasGlobalBuffer = typeof Buffer === "function" && Buffer.prototype?._isBuffer !== true; - var ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils; - var BSONDataView = class extends DataView { - static fromUint8Array(input) { - return new DataView(input.buffer, input.byteOffset, input.byteLength); - } - }; - var BSONValue = class { - get [Symbol.for("@@mdb.bson.version")]() { - return BSON_MAJOR_VERSION; - } - [Symbol.for("nodejs.util.inspect.custom")](depth, options, inspect) { - return this.inspect(depth, options, inspect); - } - }; - var Binary = class _Binary extends BSONValue { - get _bsontype() { - return "Binary"; - } - constructor(buffer2, subType) { - super(); - if (!(buffer2 == null) && typeof buffer2 === "string" && !ArrayBuffer.isView(buffer2) && !isAnyArrayBuffer(buffer2) && !Array.isArray(buffer2)) { - throw new BSONError("Binary can only be constructed from Uint8Array or number[]"); - } - this.sub_type = subType ?? _Binary.BSON_BINARY_SUBTYPE_DEFAULT; - if (buffer2 == null) { - this.buffer = ByteUtils.allocate(_Binary.BUFFER_SIZE); - this.position = 0; - } else { - this.buffer = Array.isArray(buffer2) ? ByteUtils.fromNumberArray(buffer2) : ByteUtils.toLocalBufferType(buffer2); - this.position = this.buffer.byteLength; - } - } - put(byteValue) { - if (typeof byteValue === "string" && byteValue.length !== 1) { - throw new BSONError("only accepts single character String"); - } else if (typeof byteValue !== "number" && byteValue.length !== 1) - throw new BSONError("only accepts single character Uint8Array or Array"); - let decodedByte; - if (typeof byteValue === "string") { - decodedByte = byteValue.charCodeAt(0); - } else if (typeof byteValue === "number") { - decodedByte = byteValue; - } else { - decodedByte = byteValue[0]; - } - if (decodedByte < 0 || decodedByte > 255) { - throw new BSONError("only accepts number in a valid unsigned byte range 0-255"); - } - if (this.buffer.byteLength > this.position) { - this.buffer[this.position++] = decodedByte; - } else { - const newSpace = ByteUtils.allocate(_Binary.BUFFER_SIZE + this.buffer.length); - newSpace.set(this.buffer, 0); - this.buffer = newSpace; - this.buffer[this.position++] = decodedByte; - } - } - write(sequence, offset) { - offset = typeof offset === "number" ? offset : this.position; - if (this.buffer.byteLength < offset + sequence.length) { - const newSpace = ByteUtils.allocate(this.buffer.byteLength + sequence.length); - newSpace.set(this.buffer, 0); - this.buffer = newSpace; - } - if (ArrayBuffer.isView(sequence)) { - this.buffer.set(ByteUtils.toLocalBufferType(sequence), offset); - this.position = offset + sequence.byteLength > this.position ? offset + sequence.length : this.position; - } else if (typeof sequence === "string") { - throw new BSONError("input cannot be string"); - } - } - read(position, length) { - length = length && length > 0 ? length : this.position; - return this.buffer.slice(position, position + length); - } - value() { - return this.buffer.length === this.position ? this.buffer : this.buffer.subarray(0, this.position); - } - length() { - return this.position; - } - toJSON() { - return ByteUtils.toBase64(this.buffer); - } - toString(encoding) { - if (encoding === "hex") - return ByteUtils.toHex(this.buffer); - if (encoding === "base64") - return ByteUtils.toBase64(this.buffer); - if (encoding === "utf8" || encoding === "utf-8") - return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false); - return ByteUtils.toUTF8(this.buffer, 0, this.buffer.byteLength, false); - } - toExtendedJSON(options) { - options = options || {}; - const base64String = ByteUtils.toBase64(this.buffer); - const subType = Number(this.sub_type).toString(16); - if (options.legacy) { - return { - $binary: base64String, - $type: subType.length === 1 ? "0" + subType : subType - }; - } - return { - $binary: { - base64: base64String, - subType: subType.length === 1 ? "0" + subType : subType - } - }; - } - toUUID() { - if (this.sub_type === _Binary.SUBTYPE_UUID) { - return new UUID(this.buffer.slice(0, this.position)); - } - throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${_Binary.SUBTYPE_UUID}" is currently supported.`); - } - static createFromHexString(hex, subType) { - return new _Binary(ByteUtils.fromHex(hex), subType); - } - static createFromBase64(base64, subType) { - return new _Binary(ByteUtils.fromBase64(base64), subType); - } - static fromExtendedJSON(doc, options) { - options = options || {}; - let data; - let type; - if ("$binary" in doc) { - if (options.legacy && typeof doc.$binary === "string" && "$type" in doc) { - type = doc.$type ? parseInt(doc.$type, 16) : 0; - data = ByteUtils.fromBase64(doc.$binary); - } else { - if (typeof doc.$binary !== "string") { - type = doc.$binary.subType ? parseInt(doc.$binary.subType, 16) : 0; - data = ByteUtils.fromBase64(doc.$binary.base64); - } - } - } else if ("$uuid" in doc) { - type = 4; - data = UUID.bytesFromString(doc.$uuid); - } - if (!data) { - throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`); - } - return type === BSON_BINARY_SUBTYPE_UUID_NEW ? new UUID(data) : new _Binary(data, type); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - const base64 = ByteUtils.toBase64(this.buffer.subarray(0, this.position)); - const base64Arg = inspect(base64, options); - const subTypeArg = inspect(this.sub_type, options); - return `Binary.createFromBase64(${base64Arg}, ${subTypeArg})`; - } - }; - Binary.BSON_BINARY_SUBTYPE_DEFAULT = 0; - Binary.BUFFER_SIZE = 256; - Binary.SUBTYPE_DEFAULT = 0; - Binary.SUBTYPE_FUNCTION = 1; - Binary.SUBTYPE_BYTE_ARRAY = 2; - Binary.SUBTYPE_UUID_OLD = 3; - Binary.SUBTYPE_UUID = 4; - Binary.SUBTYPE_MD5 = 5; - Binary.SUBTYPE_ENCRYPTED = 6; - Binary.SUBTYPE_COLUMN = 7; - Binary.SUBTYPE_USER_DEFINED = 128; - var UUID_BYTE_LENGTH = 16; - var UUID_WITHOUT_DASHES = /^[0-9A-F]{32}$/i; - var UUID_WITH_DASHES = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i; - var UUID = class _UUID extends Binary { - constructor(input) { - let bytes; - if (input == null) { - bytes = _UUID.generate(); - } else if (input instanceof _UUID) { - bytes = ByteUtils.toLocalBufferType(new Uint8Array(input.buffer)); - } else if (ArrayBuffer.isView(input) && input.byteLength === UUID_BYTE_LENGTH) { - bytes = ByteUtils.toLocalBufferType(input); - } else if (typeof input === "string") { - bytes = _UUID.bytesFromString(input); - } else { - throw new BSONError("Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)."); - } - super(bytes, BSON_BINARY_SUBTYPE_UUID_NEW); - } - get id() { - return this.buffer; - } - set id(value) { - this.buffer = value; - } - toHexString(includeDashes = true) { - if (includeDashes) { - return [ - ByteUtils.toHex(this.buffer.subarray(0, 4)), - ByteUtils.toHex(this.buffer.subarray(4, 6)), - ByteUtils.toHex(this.buffer.subarray(6, 8)), - ByteUtils.toHex(this.buffer.subarray(8, 10)), - ByteUtils.toHex(this.buffer.subarray(10, 16)) - ].join("-"); - } - return ByteUtils.toHex(this.buffer); - } - toString(encoding) { - if (encoding === "hex") - return ByteUtils.toHex(this.id); - if (encoding === "base64") - return ByteUtils.toBase64(this.id); - return this.toHexString(); - } - toJSON() { - return this.toHexString(); - } - equals(otherId) { - if (!otherId) { - return false; - } - if (otherId instanceof _UUID) { - return ByteUtils.equals(otherId.id, this.id); - } - try { - return ByteUtils.equals(new _UUID(otherId).id, this.id); - } catch { - return false; - } - } - toBinary() { - return new Binary(this.id, Binary.SUBTYPE_UUID); - } - static generate() { - const bytes = ByteUtils.randomBytes(UUID_BYTE_LENGTH); - bytes[6] = bytes[6] & 15 | 64; - bytes[8] = bytes[8] & 63 | 128; - return bytes; - } - static isValid(input) { - if (!input) { - return false; - } - if (typeof input === "string") { - return _UUID.isValidUUIDString(input); - } - if (isUint8Array(input)) { - return input.byteLength === UUID_BYTE_LENGTH; - } - return input._bsontype === "Binary" && input.sub_type === this.SUBTYPE_UUID && input.buffer.byteLength === 16; - } - static createFromHexString(hexString) { - const buffer2 = _UUID.bytesFromString(hexString); - return new _UUID(buffer2); - } - static createFromBase64(base64) { - return new _UUID(ByteUtils.fromBase64(base64)); - } - static bytesFromString(representation) { - if (!_UUID.isValidUUIDString(representation)) { - throw new BSONError("UUID string representation must be 32 hex digits or canonical hyphenated representation"); - } - return ByteUtils.fromHex(representation.replace(/-/g, "")); - } - static isValidUUIDString(representation) { - return UUID_WITHOUT_DASHES.test(representation) || UUID_WITH_DASHES.test(representation); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - return `new UUID(${inspect(this.toHexString(), options)})`; - } - }; - var Code = class _Code extends BSONValue { - get _bsontype() { - return "Code"; - } - constructor(code, scope) { - super(); - this.code = code.toString(); - this.scope = scope ?? null; - } - toJSON() { - if (this.scope != null) { - return { code: this.code, scope: this.scope }; - } - return { code: this.code }; - } - toExtendedJSON() { - if (this.scope) { - return { $code: this.code, $scope: this.scope }; - } - return { $code: this.code }; - } - static fromExtendedJSON(doc) { - return new _Code(doc.$code, doc.$scope); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - let parametersString = inspect(this.code, options); - const multiLineFn = parametersString.includes("\n"); - if (this.scope != null) { - parametersString += `,${multiLineFn ? "\n" : " "}${inspect(this.scope, options)}`; - } - const endingNewline = multiLineFn && this.scope === null; - return `new Code(${multiLineFn ? "\n" : ""}${parametersString}${endingNewline ? "\n" : ""})`; - } - }; - function isDBRefLike(value) { - return value != null && typeof value === "object" && "$id" in value && value.$id != null && "$ref" in value && typeof value.$ref === "string" && (!("$db" in value) || "$db" in value && typeof value.$db === "string"); - } - var DBRef = class _DBRef extends BSONValue { - get _bsontype() { - return "DBRef"; - } - constructor(collection, oid, db, fields) { - super(); - const parts = collection.split("."); - if (parts.length === 2) { - db = parts.shift(); - collection = parts.shift(); - } - this.collection = collection; - this.oid = oid; - this.db = db; - this.fields = fields || {}; - } - get namespace() { - return this.collection; - } - set namespace(value) { - this.collection = value; - } - toJSON() { - const o = Object.assign({ - $ref: this.collection, - $id: this.oid - }, this.fields); - if (this.db != null) - o.$db = this.db; - return o; - } - toExtendedJSON(options) { - options = options || {}; - let o = { - $ref: this.collection, - $id: this.oid - }; - if (options.legacy) { - return o; - } - if (this.db) - o.$db = this.db; - o = Object.assign(o, this.fields); - return o; - } - static fromExtendedJSON(doc) { - const copy = Object.assign({}, doc); - delete copy.$ref; - delete copy.$id; - delete copy.$db; - return new _DBRef(doc.$ref, doc.$id, doc.$db, copy); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - const args = [ - inspect(this.namespace, options), - inspect(this.oid, options), - ...this.db ? [inspect(this.db, options)] : [], - ...Object.keys(this.fields).length > 0 ? [inspect(this.fields, options)] : [] - ]; - args[1] = inspect === defaultInspect ? `new ObjectId(${args[1]})` : args[1]; - return `new DBRef(${args.join(", ")})`; - } - }; - var wasm = void 0; - try { - wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11])), {}).exports; - } catch { - } - var TWO_PWR_16_DBL = 1 << 16; - var TWO_PWR_24_DBL = 1 << 24; - var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; - var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; - var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; - var INT_CACHE = {}; - var UINT_CACHE = {}; - var MAX_INT64_STRING_LENGTH = 20; - var DECIMAL_REG_EX = /^(\+?0|(\+|-)?[1-9][0-9]*)$/; - var Long = class _Long extends BSONValue { - get _bsontype() { - return "Long"; - } - get __isLong__() { - return true; - } - constructor(low = 0, high, unsigned) { - super(); - if (typeof low === "bigint") { - Object.assign(this, _Long.fromBigInt(low, !!high)); - } else if (typeof low === "string") { - Object.assign(this, _Long.fromString(low, !!high)); - } else { - this.low = low | 0; - this.high = high | 0; - this.unsigned = !!unsigned; - } - } - static fromBits(lowBits, highBits, unsigned) { - return new _Long(lowBits, highBits, unsigned); - } - static fromInt(value, unsigned) { - let obj, cachedObj, cache; - if (unsigned) { - value >>>= 0; - if (cache = 0 <= value && value < 256) { - cachedObj = UINT_CACHE[value]; - if (cachedObj) - return cachedObj; - } - obj = _Long.fromBits(value, (value | 0) < 0 ? -1 : 0, true); - if (cache) - UINT_CACHE[value] = obj; - return obj; - } else { - value |= 0; - if (cache = -128 <= value && value < 128) { - cachedObj = INT_CACHE[value]; - if (cachedObj) - return cachedObj; - } - obj = _Long.fromBits(value, value < 0 ? -1 : 0, false); - if (cache) - INT_CACHE[value] = obj; - return obj; - } - } - static fromNumber(value, unsigned) { - if (isNaN(value)) - return unsigned ? _Long.UZERO : _Long.ZERO; - if (unsigned) { - if (value < 0) - return _Long.UZERO; - if (value >= TWO_PWR_64_DBL) - return _Long.MAX_UNSIGNED_VALUE; - } else { - if (value <= -TWO_PWR_63_DBL) - return _Long.MIN_VALUE; - if (value + 1 >= TWO_PWR_63_DBL) - return _Long.MAX_VALUE; - } - if (value < 0) - return _Long.fromNumber(-value, unsigned).neg(); - return _Long.fromBits(value % TWO_PWR_32_DBL | 0, value / TWO_PWR_32_DBL | 0, unsigned); - } - static fromBigInt(value, unsigned) { - return _Long.fromString(value.toString(), unsigned); - } - static fromString(str, unsigned, radix) { - if (str.length === 0) - throw new BSONError("empty string"); - if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") - return _Long.ZERO; - if (typeof unsigned === "number") { - radix = unsigned, unsigned = false; - } else { - unsigned = !!unsigned; - } - radix = radix || 10; - if (radix < 2 || 36 < radix) - throw new BSONError("radix"); - let p; - if ((p = str.indexOf("-")) > 0) - throw new BSONError("interior hyphen"); - else if (p === 0) { - return _Long.fromString(str.substring(1), unsigned, radix).neg(); - } - const radixToPower = _Long.fromNumber(Math.pow(radix, 8)); - let result = _Long.ZERO; - for (let i = 0; i < str.length; i += 8) { - const size = Math.min(8, str.length - i), value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - const power = _Long.fromNumber(Math.pow(radix, size)); - result = result.mul(power).add(_Long.fromNumber(value)); - } else { - result = result.mul(radixToPower); - result = result.add(_Long.fromNumber(value)); - } - } - result.unsigned = unsigned; - return result; - } - static fromBytes(bytes, unsigned, le) { - return le ? _Long.fromBytesLE(bytes, unsigned) : _Long.fromBytesBE(bytes, unsigned); - } - static fromBytesLE(bytes, unsigned) { - return new _Long(bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24, bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24, unsigned); - } - static fromBytesBE(bytes, unsigned) { - return new _Long(bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7], bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], unsigned); - } - static isLong(value) { - return value != null && typeof value === "object" && "__isLong__" in value && value.__isLong__ === true; - } - static fromValue(val, unsigned) { - if (typeof val === "number") - return _Long.fromNumber(val, unsigned); - if (typeof val === "string") - return _Long.fromString(val, unsigned); - return _Long.fromBits(val.low, val.high, typeof unsigned === "boolean" ? unsigned : val.unsigned); - } - add(addend) { - if (!_Long.isLong(addend)) - addend = _Long.fromValue(addend); - const a48 = this.high >>> 16; - const a32 = this.high & 65535; - const a16 = this.low >>> 16; - const a00 = this.low & 65535; - const b48 = addend.high >>> 16; - const b32 = addend.high & 65535; - const b16 = addend.low >>> 16; - const b00 = addend.low & 65535; - let c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 65535; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 65535; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 65535; - c48 += a48 + b48; - c48 &= 65535; - return _Long.fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); - } - and(other) { - if (!_Long.isLong(other)) - other = _Long.fromValue(other); - return _Long.fromBits(this.low & other.low, this.high & other.high, this.unsigned); - } - compare(other) { - if (!_Long.isLong(other)) - other = _Long.fromValue(other); - if (this.eq(other)) - return 0; - const thisNeg = this.isNegative(), otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) - return -1; - if (!thisNeg && otherNeg) - return 1; - if (!this.unsigned) - return this.sub(other).isNegative() ? -1 : 1; - return other.high >>> 0 > this.high >>> 0 || other.high === this.high && other.low >>> 0 > this.low >>> 0 ? -1 : 1; - } - comp(other) { - return this.compare(other); - } - divide(divisor) { - if (!_Long.isLong(divisor)) - divisor = _Long.fromValue(divisor); - if (divisor.isZero()) - throw new BSONError("division by zero"); - if (wasm) { - if (!this.unsigned && this.high === -2147483648 && divisor.low === -1 && divisor.high === -1) { - return this; - } - const low = (this.unsigned ? wasm.div_u : wasm.div_s)(this.low, this.high, divisor.low, divisor.high); - return _Long.fromBits(low, wasm.get_high(), this.unsigned); - } - if (this.isZero()) - return this.unsigned ? _Long.UZERO : _Long.ZERO; - let approx, rem, res; - if (!this.unsigned) { - if (this.eq(_Long.MIN_VALUE)) { - if (divisor.eq(_Long.ONE) || divisor.eq(_Long.NEG_ONE)) - return _Long.MIN_VALUE; - else if (divisor.eq(_Long.MIN_VALUE)) - return _Long.ONE; - else { - const halfThis = this.shr(1); - approx = halfThis.div(divisor).shl(1); - if (approx.eq(_Long.ZERO)) { - return divisor.isNegative() ? _Long.ONE : _Long.NEG_ONE; - } else { - rem = this.sub(divisor.mul(approx)); - res = approx.add(rem.div(divisor)); - return res; - } - } - } else if (divisor.eq(_Long.MIN_VALUE)) - return this.unsigned ? _Long.UZERO : _Long.ZERO; - if (this.isNegative()) { - if (divisor.isNegative()) - return this.neg().div(divisor.neg()); - return this.neg().div(divisor).neg(); - } else if (divisor.isNegative()) - return this.div(divisor.neg()).neg(); - res = _Long.ZERO; - } else { - if (!divisor.unsigned) - divisor = divisor.toUnsigned(); - if (divisor.gt(this)) - return _Long.UZERO; - if (divisor.gt(this.shru(1))) - return _Long.UONE; - res = _Long.UZERO; - } - rem = this; - while (rem.gte(divisor)) { - approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber())); - const log2 = Math.ceil(Math.log(approx) / Math.LN2); - const delta = log2 <= 48 ? 1 : Math.pow(2, log2 - 48); - let approxRes = _Long.fromNumber(approx); - let approxRem = approxRes.mul(divisor); - while (approxRem.isNegative() || approxRem.gt(rem)) { - approx -= delta; - approxRes = _Long.fromNumber(approx, this.unsigned); - approxRem = approxRes.mul(divisor); - } - if (approxRes.isZero()) - approxRes = _Long.ONE; - res = res.add(approxRes); - rem = rem.sub(approxRem); - } - return res; - } - div(divisor) { - return this.divide(divisor); - } - equals(other) { - if (!_Long.isLong(other)) - other = _Long.fromValue(other); - if (this.unsigned !== other.unsigned && this.high >>> 31 === 1 && other.high >>> 31 === 1) - return false; - return this.high === other.high && this.low === other.low; - } - eq(other) { - return this.equals(other); - } - getHighBits() { - return this.high; - } - getHighBitsUnsigned() { - return this.high >>> 0; - } - getLowBits() { - return this.low; - } - getLowBitsUnsigned() { - return this.low >>> 0; - } - getNumBitsAbs() { - if (this.isNegative()) { - return this.eq(_Long.MIN_VALUE) ? 64 : this.neg().getNumBitsAbs(); - } - const val = this.high !== 0 ? this.high : this.low; - let bit; - for (bit = 31; bit > 0; bit--) - if ((val & 1 << bit) !== 0) - break; - return this.high !== 0 ? bit + 33 : bit + 1; - } - greaterThan(other) { - return this.comp(other) > 0; - } - gt(other) { - return this.greaterThan(other); - } - greaterThanOrEqual(other) { - return this.comp(other) >= 0; - } - gte(other) { - return this.greaterThanOrEqual(other); - } - ge(other) { - return this.greaterThanOrEqual(other); - } - isEven() { - return (this.low & 1) === 0; - } - isNegative() { - return !this.unsigned && this.high < 0; - } - isOdd() { - return (this.low & 1) === 1; - } - isPositive() { - return this.unsigned || this.high >= 0; - } - isZero() { - return this.high === 0 && this.low === 0; - } - lessThan(other) { - return this.comp(other) < 0; - } - lt(other) { - return this.lessThan(other); - } - lessThanOrEqual(other) { - return this.comp(other) <= 0; - } - lte(other) { - return this.lessThanOrEqual(other); - } - modulo(divisor) { - if (!_Long.isLong(divisor)) - divisor = _Long.fromValue(divisor); - if (wasm) { - const low = (this.unsigned ? wasm.rem_u : wasm.rem_s)(this.low, this.high, divisor.low, divisor.high); - return _Long.fromBits(low, wasm.get_high(), this.unsigned); - } - return this.sub(this.div(divisor).mul(divisor)); - } - mod(divisor) { - return this.modulo(divisor); - } - rem(divisor) { - return this.modulo(divisor); - } - multiply(multiplier) { - if (this.isZero()) - return _Long.ZERO; - if (!_Long.isLong(multiplier)) - multiplier = _Long.fromValue(multiplier); - if (wasm) { - const low = wasm.mul(this.low, this.high, multiplier.low, multiplier.high); - return _Long.fromBits(low, wasm.get_high(), this.unsigned); - } - if (multiplier.isZero()) - return _Long.ZERO; - if (this.eq(_Long.MIN_VALUE)) - return multiplier.isOdd() ? _Long.MIN_VALUE : _Long.ZERO; - if (multiplier.eq(_Long.MIN_VALUE)) - return this.isOdd() ? _Long.MIN_VALUE : _Long.ZERO; - if (this.isNegative()) { - if (multiplier.isNegative()) - return this.neg().mul(multiplier.neg()); - else - return this.neg().mul(multiplier).neg(); - } else if (multiplier.isNegative()) - return this.mul(multiplier.neg()).neg(); - if (this.lt(_Long.TWO_PWR_24) && multiplier.lt(_Long.TWO_PWR_24)) - return _Long.fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned); - const a48 = this.high >>> 16; - const a32 = this.high & 65535; - const a16 = this.low >>> 16; - const a00 = this.low & 65535; - const b48 = multiplier.high >>> 16; - const b32 = multiplier.high & 65535; - const b16 = multiplier.low >>> 16; - const b00 = multiplier.low & 65535; - let c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 65535; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 65535; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 65535; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 65535; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 65535; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 65535; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 65535; - return _Long.fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); - } - mul(multiplier) { - return this.multiply(multiplier); - } - negate() { - if (!this.unsigned && this.eq(_Long.MIN_VALUE)) - return _Long.MIN_VALUE; - return this.not().add(_Long.ONE); - } - neg() { - return this.negate(); - } - not() { - return _Long.fromBits(~this.low, ~this.high, this.unsigned); - } - notEquals(other) { - return !this.equals(other); - } - neq(other) { - return this.notEquals(other); - } - ne(other) { - return this.notEquals(other); - } - or(other) { - if (!_Long.isLong(other)) - other = _Long.fromValue(other); - return _Long.fromBits(this.low | other.low, this.high | other.high, this.unsigned); - } - shiftLeft(numBits) { - if (_Long.isLong(numBits)) - numBits = numBits.toInt(); - if ((numBits &= 63) === 0) - return this; - else if (numBits < 32) - return _Long.fromBits(this.low << numBits, this.high << numBits | this.low >>> 32 - numBits, this.unsigned); - else - return _Long.fromBits(0, this.low << numBits - 32, this.unsigned); - } - shl(numBits) { - return this.shiftLeft(numBits); - } - shiftRight(numBits) { - if (_Long.isLong(numBits)) - numBits = numBits.toInt(); - if ((numBits &= 63) === 0) - return this; - else if (numBits < 32) - return _Long.fromBits(this.low >>> numBits | this.high << 32 - numBits, this.high >> numBits, this.unsigned); - else - return _Long.fromBits(this.high >> numBits - 32, this.high >= 0 ? 0 : -1, this.unsigned); - } - shr(numBits) { - return this.shiftRight(numBits); - } - shiftRightUnsigned(numBits) { - if (_Long.isLong(numBits)) - numBits = numBits.toInt(); - numBits &= 63; - if (numBits === 0) - return this; - else { - const high = this.high; - if (numBits < 32) { - const low = this.low; - return _Long.fromBits(low >>> numBits | high << 32 - numBits, high >>> numBits, this.unsigned); - } else if (numBits === 32) - return _Long.fromBits(high, 0, this.unsigned); - else - return _Long.fromBits(high >>> numBits - 32, 0, this.unsigned); - } - } - shr_u(numBits) { - return this.shiftRightUnsigned(numBits); - } - shru(numBits) { - return this.shiftRightUnsigned(numBits); - } - subtract(subtrahend) { - if (!_Long.isLong(subtrahend)) - subtrahend = _Long.fromValue(subtrahend); - return this.add(subtrahend.neg()); - } - sub(subtrahend) { - return this.subtract(subtrahend); - } - toInt() { - return this.unsigned ? this.low >>> 0 : this.low; - } - toNumber() { - if (this.unsigned) - return (this.high >>> 0) * TWO_PWR_32_DBL + (this.low >>> 0); - return this.high * TWO_PWR_32_DBL + (this.low >>> 0); - } - toBigInt() { - return BigInt(this.toString()); - } - toBytes(le) { - return le ? this.toBytesLE() : this.toBytesBE(); - } - toBytesLE() { - const hi = this.high, lo = this.low; - return [ - lo & 255, - lo >>> 8 & 255, - lo >>> 16 & 255, - lo >>> 24, - hi & 255, - hi >>> 8 & 255, - hi >>> 16 & 255, - hi >>> 24 - ]; - } - toBytesBE() { - const hi = this.high, lo = this.low; - return [ - hi >>> 24, - hi >>> 16 & 255, - hi >>> 8 & 255, - hi & 255, - lo >>> 24, - lo >>> 16 & 255, - lo >>> 8 & 255, - lo & 255 - ]; - } - toSigned() { - if (!this.unsigned) - return this; - return _Long.fromBits(this.low, this.high, false); - } - toString(radix) { - radix = radix || 10; - if (radix < 2 || 36 < radix) - throw new BSONError("radix"); - if (this.isZero()) - return "0"; - if (this.isNegative()) { - if (this.eq(_Long.MIN_VALUE)) { - const radixLong = _Long.fromNumber(radix), div = this.div(radixLong), rem1 = div.mul(radixLong).sub(this); - return div.toString(radix) + rem1.toInt().toString(radix); - } else - return "-" + this.neg().toString(radix); - } - const radixToPower = _Long.fromNumber(Math.pow(radix, 6), this.unsigned); - let rem = this; - let result = ""; - while (true) { - const remDiv = rem.div(radixToPower); - const intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0; - let digits = intval.toString(radix); - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) - digits = "0" + digits; - result = "" + digits + result; - } - } - } - toUnsigned() { - if (this.unsigned) - return this; - return _Long.fromBits(this.low, this.high, true); - } - xor(other) { - if (!_Long.isLong(other)) - other = _Long.fromValue(other); - return _Long.fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned); - } - eqz() { - return this.isZero(); - } - le(other) { - return this.lessThanOrEqual(other); - } - toExtendedJSON(options) { - if (options && options.relaxed) - return this.toNumber(); - return { $numberLong: this.toString() }; - } - static fromExtendedJSON(doc, options) { - const { useBigInt64 = false, relaxed = true } = { ...options }; - if (doc.$numberLong.length > MAX_INT64_STRING_LENGTH) { - throw new BSONError("$numberLong string is too long"); - } - if (!DECIMAL_REG_EX.test(doc.$numberLong)) { - throw new BSONError(`$numberLong string "${doc.$numberLong}" is in an invalid format`); - } - if (useBigInt64) { - const bigIntResult = BigInt(doc.$numberLong); - return BigInt.asIntN(64, bigIntResult); - } - const longResult = _Long.fromString(doc.$numberLong); - if (relaxed) { - return longResult.toNumber(); - } - return longResult; - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - const longVal = inspect(this.toString(), options); - const unsignedVal = this.unsigned ? `, ${inspect(this.unsigned, options)}` : ""; - return `new Long(${longVal}${unsignedVal})`; - } - }; - Long.TWO_PWR_24 = Long.fromInt(TWO_PWR_24_DBL); - Long.MAX_UNSIGNED_VALUE = Long.fromBits(4294967295 | 0, 4294967295 | 0, true); - Long.ZERO = Long.fromInt(0); - Long.UZERO = Long.fromInt(0, true); - Long.ONE = Long.fromInt(1); - Long.UONE = Long.fromInt(1, true); - Long.NEG_ONE = Long.fromInt(-1); - Long.MAX_VALUE = Long.fromBits(4294967295 | 0, 2147483647 | 0, false); - Long.MIN_VALUE = Long.fromBits(0, 2147483648 | 0, false); - var PARSE_STRING_REGEXP = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/; - var PARSE_INF_REGEXP = /^(\+|-)?(Infinity|inf)$/i; - var PARSE_NAN_REGEXP = /^(\+|-)?NaN$/i; - var EXPONENT_MAX = 6111; - var EXPONENT_MIN = -6176; - var EXPONENT_BIAS = 6176; - var MAX_DIGITS = 34; - var NAN_BUFFER = ByteUtils.fromNumberArray([ - 124, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ].reverse()); - var INF_NEGATIVE_BUFFER = ByteUtils.fromNumberArray([ - 248, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ].reverse()); - var INF_POSITIVE_BUFFER = ByteUtils.fromNumberArray([ - 120, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ].reverse()); - var EXPONENT_REGEX = /^([-+])?(\d+)?$/; - var COMBINATION_MASK = 31; - var EXPONENT_MASK = 16383; - var COMBINATION_INFINITY = 30; - var COMBINATION_NAN = 31; - function isDigit(value) { - return !isNaN(parseInt(value, 10)); - } - function divideu128(value) { - const DIVISOR = Long.fromNumber(1e3 * 1e3 * 1e3); - let _rem = Long.fromNumber(0); - if (!value.parts[0] && !value.parts[1] && !value.parts[2] && !value.parts[3]) { - return { quotient: value, rem: _rem }; - } - for (let i = 0; i <= 3; i++) { - _rem = _rem.shiftLeft(32); - _rem = _rem.add(new Long(value.parts[i], 0)); - value.parts[i] = _rem.div(DIVISOR).low; - _rem = _rem.modulo(DIVISOR); - } - return { quotient: value, rem: _rem }; - } - function multiply64x2(left, right) { - if (!left && !right) { - return { high: Long.fromNumber(0), low: Long.fromNumber(0) }; - } - const leftHigh = left.shiftRightUnsigned(32); - const leftLow = new Long(left.getLowBits(), 0); - const rightHigh = right.shiftRightUnsigned(32); - const rightLow = new Long(right.getLowBits(), 0); - let productHigh = leftHigh.multiply(rightHigh); - let productMid = leftHigh.multiply(rightLow); - const productMid2 = leftLow.multiply(rightHigh); - let productLow = leftLow.multiply(rightLow); - productHigh = productHigh.add(productMid.shiftRightUnsigned(32)); - productMid = new Long(productMid.getLowBits(), 0).add(productMid2).add(productLow.shiftRightUnsigned(32)); - productHigh = productHigh.add(productMid.shiftRightUnsigned(32)); - productLow = productMid.shiftLeft(32).add(new Long(productLow.getLowBits(), 0)); - return { high: productHigh, low: productLow }; - } - function lessThan(left, right) { - const uhleft = left.high >>> 0; - const uhright = right.high >>> 0; - if (uhleft < uhright) { - return true; - } else if (uhleft === uhright) { - const ulleft = left.low >>> 0; - const ulright = right.low >>> 0; - if (ulleft < ulright) - return true; - } - return false; - } - function invalidErr(string, message) { - throw new BSONError(`"${string}" is not a valid Decimal128 string - ${message}`); - } - var Decimal128 = class _Decimal128 extends BSONValue { - get _bsontype() { - return "Decimal128"; - } - constructor(bytes) { - super(); - if (typeof bytes === "string") { - this.bytes = _Decimal128.fromString(bytes).bytes; - } else if (isUint8Array(bytes)) { - if (bytes.byteLength !== 16) { - throw new BSONError("Decimal128 must take a Buffer of 16 bytes"); - } - this.bytes = bytes; - } else { - throw new BSONError("Decimal128 must take a Buffer or string"); - } - } - static fromString(representation) { - return _Decimal128._fromString(representation, { allowRounding: false }); - } - static fromStringWithRounding(representation) { - return _Decimal128._fromString(representation, { allowRounding: true }); - } - static _fromString(representation, options) { - let isNegative = false; - let sawSign = false; - let sawRadix = false; - let foundNonZero = false; - let significantDigits = 0; - let nDigitsRead = 0; - let nDigits = 0; - let radixPosition = 0; - let firstNonZero = 0; - const digits = [0]; - let nDigitsStored = 0; - let digitsInsert = 0; - let lastDigit = 0; - let exponent = 0; - let significandHigh = new Long(0, 0); - let significandLow = new Long(0, 0); - let biasedExponent = 0; - let index = 0; - if (representation.length >= 7e3) { - throw new BSONError("" + representation + " not a valid Decimal128 string"); - } - const stringMatch = representation.match(PARSE_STRING_REGEXP); - const infMatch = representation.match(PARSE_INF_REGEXP); - const nanMatch = representation.match(PARSE_NAN_REGEXP); - if (!stringMatch && !infMatch && !nanMatch || representation.length === 0) { - throw new BSONError("" + representation + " not a valid Decimal128 string"); - } - if (stringMatch) { - const unsignedNumber = stringMatch[2]; - const e = stringMatch[4]; - const expSign = stringMatch[5]; - const expNumber = stringMatch[6]; - if (e && expNumber === void 0) - invalidErr(representation, "missing exponent power"); - if (e && unsignedNumber === void 0) - invalidErr(representation, "missing exponent base"); - if (e === void 0 && (expSign || expNumber)) { - invalidErr(representation, "missing e before exponent"); - } - } - if (representation[index] === "+" || representation[index] === "-") { - sawSign = true; - isNegative = representation[index++] === "-"; - } - if (!isDigit(representation[index]) && representation[index] !== ".") { - if (representation[index] === "i" || representation[index] === "I") { - return new _Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER); - } else if (representation[index] === "N") { - return new _Decimal128(NAN_BUFFER); - } - } - while (isDigit(representation[index]) || representation[index] === ".") { - if (representation[index] === ".") { - if (sawRadix) - invalidErr(representation, "contains multiple periods"); - sawRadix = true; - index = index + 1; - continue; - } - if (nDigitsStored < MAX_DIGITS) { - if (representation[index] !== "0" || foundNonZero) { - if (!foundNonZero) { - firstNonZero = nDigitsRead; - } - foundNonZero = true; - digits[digitsInsert++] = parseInt(representation[index], 10); - nDigitsStored = nDigitsStored + 1; - } - } - if (foundNonZero) - nDigits = nDigits + 1; - if (sawRadix) - radixPosition = radixPosition + 1; - nDigitsRead = nDigitsRead + 1; - index = index + 1; - } - if (sawRadix && !nDigitsRead) - throw new BSONError("" + representation + " not a valid Decimal128 string"); - if (representation[index] === "e" || representation[index] === "E") { - const match = representation.substr(++index).match(EXPONENT_REGEX); - if (!match || !match[2]) - return new _Decimal128(NAN_BUFFER); - exponent = parseInt(match[0], 10); - index = index + match[0].length; - } - if (representation[index]) - return new _Decimal128(NAN_BUFFER); - if (!nDigitsStored) { - digits[0] = 0; - nDigits = 1; - nDigitsStored = 1; - significantDigits = 0; - } else { - lastDigit = nDigitsStored - 1; - significantDigits = nDigits; - if (significantDigits !== 1) { - while (representation[firstNonZero + significantDigits - 1 + Number(sawSign) + Number(sawRadix)] === "0") { - significantDigits = significantDigits - 1; - } - } - } - if (exponent <= radixPosition && radixPosition > exponent + (1 << 14)) { - exponent = EXPONENT_MIN; - } else { - exponent = exponent - radixPosition; - } - while (exponent > EXPONENT_MAX) { - lastDigit = lastDigit + 1; - if (lastDigit >= MAX_DIGITS) { - if (significantDigits === 0) { - exponent = EXPONENT_MAX; - break; - } - invalidErr(representation, "overflow"); - } - exponent = exponent - 1; - } - if (options.allowRounding) { - while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) { - if (lastDigit === 0 && significantDigits < nDigitsStored) { - exponent = EXPONENT_MIN; - significantDigits = 0; - break; - } - if (nDigitsStored < nDigits) { - nDigits = nDigits - 1; - } else { - lastDigit = lastDigit - 1; - } - if (exponent < EXPONENT_MAX) { - exponent = exponent + 1; - } else { - const digitsString = digits.join(""); - if (digitsString.match(/^0+$/)) { - exponent = EXPONENT_MAX; - break; - } - invalidErr(representation, "overflow"); - } - } - if (lastDigit + 1 < significantDigits) { - let endOfString = nDigitsRead; - if (sawRadix) { - firstNonZero = firstNonZero + 1; - endOfString = endOfString + 1; - } - if (sawSign) { - firstNonZero = firstNonZero + 1; - endOfString = endOfString + 1; - } - const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10); - let roundBit = 0; - if (roundDigit >= 5) { - roundBit = 1; - if (roundDigit === 5) { - roundBit = digits[lastDigit] % 2 === 1 ? 1 : 0; - for (let i = firstNonZero + lastDigit + 2; i < endOfString; i++) { - if (parseInt(representation[i], 10)) { - roundBit = 1; - break; - } - } - } - } - if (roundBit) { - let dIdx = lastDigit; - for (; dIdx >= 0; dIdx--) { - if (++digits[dIdx] > 9) { - digits[dIdx] = 0; - if (dIdx === 0) { - if (exponent < EXPONENT_MAX) { - exponent = exponent + 1; - digits[dIdx] = 1; - } else { - return new _Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER); - } - } - } else { - break; - } - } - } - } - } else { - while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) { - if (lastDigit === 0) { - if (significantDigits === 0) { - exponent = EXPONENT_MIN; - break; - } - invalidErr(representation, "exponent underflow"); - } - if (nDigitsStored < nDigits) { - if (representation[nDigits - 1 + Number(sawSign) + Number(sawRadix)] !== "0" && significantDigits !== 0) { - invalidErr(representation, "inexact rounding"); - } - nDigits = nDigits - 1; - } else { - if (digits[lastDigit] !== 0) { - invalidErr(representation, "inexact rounding"); - } - lastDigit = lastDigit - 1; - } - if (exponent < EXPONENT_MAX) { - exponent = exponent + 1; - } else { - invalidErr(representation, "overflow"); - } - } - if (lastDigit + 1 < significantDigits) { - if (sawRadix) { - firstNonZero = firstNonZero + 1; - } - if (sawSign) { - firstNonZero = firstNonZero + 1; - } - const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10); - if (roundDigit !== 0) { - invalidErr(representation, "inexact rounding"); - } - } - } - significandHigh = Long.fromNumber(0); - significandLow = Long.fromNumber(0); - if (significantDigits === 0) { - significandHigh = Long.fromNumber(0); - significandLow = Long.fromNumber(0); - } else if (lastDigit < 17) { - let dIdx = 0; - significandLow = Long.fromNumber(digits[dIdx++]); - significandHigh = new Long(0, 0); - for (; dIdx <= lastDigit; dIdx++) { - significandLow = significandLow.multiply(Long.fromNumber(10)); - significandLow = significandLow.add(Long.fromNumber(digits[dIdx])); - } - } else { - let dIdx = 0; - significandHigh = Long.fromNumber(digits[dIdx++]); - for (; dIdx <= lastDigit - 17; dIdx++) { - significandHigh = significandHigh.multiply(Long.fromNumber(10)); - significandHigh = significandHigh.add(Long.fromNumber(digits[dIdx])); - } - significandLow = Long.fromNumber(digits[dIdx++]); - for (; dIdx <= lastDigit; dIdx++) { - significandLow = significandLow.multiply(Long.fromNumber(10)); - significandLow = significandLow.add(Long.fromNumber(digits[dIdx])); - } - } - const significand = multiply64x2(significandHigh, Long.fromString("100000000000000000")); - significand.low = significand.low.add(significandLow); - if (lessThan(significand.low, significandLow)) { - significand.high = significand.high.add(Long.fromNumber(1)); - } - biasedExponent = exponent + EXPONENT_BIAS; - const dec = { low: Long.fromNumber(0), high: Long.fromNumber(0) }; - if (significand.high.shiftRightUnsigned(49).and(Long.fromNumber(1)).equals(Long.fromNumber(1))) { - dec.high = dec.high.or(Long.fromNumber(3).shiftLeft(61)); - dec.high = dec.high.or(Long.fromNumber(biasedExponent).and(Long.fromNumber(16383).shiftLeft(47))); - dec.high = dec.high.or(significand.high.and(Long.fromNumber(140737488355327))); - } else { - dec.high = dec.high.or(Long.fromNumber(biasedExponent & 16383).shiftLeft(49)); - dec.high = dec.high.or(significand.high.and(Long.fromNumber(562949953421311))); - } - dec.low = significand.low; - if (isNegative) { - dec.high = dec.high.or(Long.fromString("9223372036854775808")); - } - const buffer2 = ByteUtils.allocate(16); - index = 0; - buffer2[index++] = dec.low.low & 255; - buffer2[index++] = dec.low.low >> 8 & 255; - buffer2[index++] = dec.low.low >> 16 & 255; - buffer2[index++] = dec.low.low >> 24 & 255; - buffer2[index++] = dec.low.high & 255; - buffer2[index++] = dec.low.high >> 8 & 255; - buffer2[index++] = dec.low.high >> 16 & 255; - buffer2[index++] = dec.low.high >> 24 & 255; - buffer2[index++] = dec.high.low & 255; - buffer2[index++] = dec.high.low >> 8 & 255; - buffer2[index++] = dec.high.low >> 16 & 255; - buffer2[index++] = dec.high.low >> 24 & 255; - buffer2[index++] = dec.high.high & 255; - buffer2[index++] = dec.high.high >> 8 & 255; - buffer2[index++] = dec.high.high >> 16 & 255; - buffer2[index++] = dec.high.high >> 24 & 255; - return new _Decimal128(buffer2); - } - toString() { - let biased_exponent; - let significand_digits = 0; - const significand = new Array(36); - for (let i = 0; i < significand.length; i++) - significand[i] = 0; - let index = 0; - let is_zero = false; - let significand_msb; - let significand128 = { parts: [0, 0, 0, 0] }; - let j, k; - const string = []; - index = 0; - const buffer2 = this.bytes; - const low = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - const midl = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - const midh = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - const high = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - index = 0; - const dec = { - low: new Long(low, midl), - high: new Long(midh, high) - }; - if (dec.high.lessThan(Long.ZERO)) { - string.push("-"); - } - const combination = high >> 26 & COMBINATION_MASK; - if (combination >> 3 === 3) { - if (combination === COMBINATION_INFINITY) { - return string.join("") + "Infinity"; - } else if (combination === COMBINATION_NAN) { - return "NaN"; - } else { - biased_exponent = high >> 15 & EXPONENT_MASK; - significand_msb = 8 + (high >> 14 & 1); - } - } else { - significand_msb = high >> 14 & 7; - biased_exponent = high >> 17 & EXPONENT_MASK; - } - const exponent = biased_exponent - EXPONENT_BIAS; - significand128.parts[0] = (high & 16383) + ((significand_msb & 15) << 14); - significand128.parts[1] = midh; - significand128.parts[2] = midl; - significand128.parts[3] = low; - if (significand128.parts[0] === 0 && significand128.parts[1] === 0 && significand128.parts[2] === 0 && significand128.parts[3] === 0) { - is_zero = true; - } else { - for (k = 3; k >= 0; k--) { - let least_digits = 0; - const result = divideu128(significand128); - significand128 = result.quotient; - least_digits = result.rem.low; - if (!least_digits) - continue; - for (j = 8; j >= 0; j--) { - significand[k * 9 + j] = least_digits % 10; - least_digits = Math.floor(least_digits / 10); - } - } - } - if (is_zero) { - significand_digits = 1; - significand[index] = 0; - } else { - significand_digits = 36; - while (!significand[index]) { - significand_digits = significand_digits - 1; - index = index + 1; - } - } - const scientific_exponent = significand_digits - 1 + exponent; - if (scientific_exponent >= 34 || scientific_exponent <= -7 || exponent > 0) { - if (significand_digits > 34) { - string.push(`${0}`); - if (exponent > 0) - string.push(`E+${exponent}`); - else if (exponent < 0) - string.push(`E${exponent}`); - return string.join(""); - } - string.push(`${significand[index++]}`); - significand_digits = significand_digits - 1; - if (significand_digits) { - string.push("."); - } - for (let i = 0; i < significand_digits; i++) { - string.push(`${significand[index++]}`); - } - string.push("E"); - if (scientific_exponent > 0) { - string.push(`+${scientific_exponent}`); - } else { - string.push(`${scientific_exponent}`); - } - } else { - if (exponent >= 0) { - for (let i = 0; i < significand_digits; i++) { - string.push(`${significand[index++]}`); - } - } else { - let radix_position = significand_digits + exponent; - if (radix_position > 0) { - for (let i = 0; i < radix_position; i++) { - string.push(`${significand[index++]}`); - } - } else { - string.push("0"); - } - string.push("."); - while (radix_position++ < 0) { - string.push("0"); - } - for (let i = 0; i < significand_digits - Math.max(radix_position - 1, 0); i++) { - string.push(`${significand[index++]}`); - } - } - } - return string.join(""); - } - toJSON() { - return { $numberDecimal: this.toString() }; - } - toExtendedJSON() { - return { $numberDecimal: this.toString() }; - } - static fromExtendedJSON(doc) { - return _Decimal128.fromString(doc.$numberDecimal); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - const d128string = inspect(this.toString(), options); - return `new Decimal128(${d128string})`; - } - }; - var Double = class _Double extends BSONValue { - get _bsontype() { - return "Double"; - } - constructor(value) { - super(); - if (value instanceof Number) { - value = value.valueOf(); - } - this.value = +value; - } - valueOf() { - return this.value; - } - toJSON() { - return this.value; - } - toString(radix) { - return this.value.toString(radix); - } - toExtendedJSON(options) { - if (options && (options.legacy || options.relaxed && isFinite(this.value))) { - return this.value; - } - if (Object.is(Math.sign(this.value), -0)) { - return { $numberDouble: "-0.0" }; - } - return { - $numberDouble: Number.isInteger(this.value) ? this.value.toFixed(1) : this.value.toString() - }; - } - static fromExtendedJSON(doc, options) { - const doubleValue = parseFloat(doc.$numberDouble); - return options && options.relaxed ? doubleValue : new _Double(doubleValue); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - return `new Double(${inspect(this.value, options)})`; - } - }; - var Int32 = class _Int32 extends BSONValue { - get _bsontype() { - return "Int32"; - } - constructor(value) { - super(); - if (value instanceof Number) { - value = value.valueOf(); - } - this.value = +value | 0; - } - valueOf() { - return this.value; - } - toString(radix) { - return this.value.toString(radix); - } - toJSON() { - return this.value; - } - toExtendedJSON(options) { - if (options && (options.relaxed || options.legacy)) - return this.value; - return { $numberInt: this.value.toString() }; - } - static fromExtendedJSON(doc, options) { - return options && options.relaxed ? parseInt(doc.$numberInt, 10) : new _Int32(doc.$numberInt); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - return `new Int32(${inspect(this.value, options)})`; - } - }; - var MaxKey = class _MaxKey extends BSONValue { - get _bsontype() { - return "MaxKey"; - } - toExtendedJSON() { - return { $maxKey: 1 }; - } - static fromExtendedJSON() { - return new _MaxKey(); - } - inspect() { - return "new MaxKey()"; - } - }; - var MinKey = class _MinKey extends BSONValue { - get _bsontype() { - return "MinKey"; - } - toExtendedJSON() { - return { $minKey: 1 }; - } - static fromExtendedJSON() { - return new _MinKey(); - } - inspect() { - return "new MinKey()"; - } - }; - var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - var PROCESS_UNIQUE = null; - var kId = Symbol("id"); - var ObjectId = class _ObjectId extends BSONValue { - get _bsontype() { - return "ObjectId"; - } - constructor(inputId) { - super(); - let workingId; - if (typeof inputId === "object" && inputId && "id" in inputId) { - if (typeof inputId.id !== "string" && !ArrayBuffer.isView(inputId.id)) { - throw new BSONError("Argument passed in must have an id that is of type string or Buffer"); - } - if ("toHexString" in inputId && typeof inputId.toHexString === "function") { - workingId = ByteUtils.fromHex(inputId.toHexString()); - } else { - workingId = inputId.id; - } - } else { - workingId = inputId; - } - if (workingId == null || typeof workingId === "number") { - this[kId] = _ObjectId.generate(typeof workingId === "number" ? workingId : void 0); - } else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) { - this[kId] = ByteUtils.toLocalBufferType(workingId); - } else if (typeof workingId === "string") { - if (workingId.length === 24 && checkForHexRegExp.test(workingId)) { - this[kId] = ByteUtils.fromHex(workingId); - } else { - throw new BSONError("input must be a 24 character hex string, 12 byte Uint8Array, or an integer"); - } - } else { - throw new BSONError("Argument passed in does not match the accepted types"); - } - if (_ObjectId.cacheHexString) { - this.__id = ByteUtils.toHex(this.id); - } - } - get id() { - return this[kId]; - } - set id(value) { - this[kId] = value; - if (_ObjectId.cacheHexString) { - this.__id = ByteUtils.toHex(value); - } - } - toHexString() { - if (_ObjectId.cacheHexString && this.__id) { - return this.__id; - } - const hexString = ByteUtils.toHex(this.id); - if (_ObjectId.cacheHexString && !this.__id) { - this.__id = hexString; - } - return hexString; - } - static getInc() { - return _ObjectId.index = (_ObjectId.index + 1) % 16777215; - } - static generate(time) { - if ("number" !== typeof time) { - time = Math.floor(Date.now() / 1e3); - } - const inc = _ObjectId.getInc(); - const buffer2 = ByteUtils.allocate(12); - BSONDataView.fromUint8Array(buffer2).setUint32(0, time, false); - if (PROCESS_UNIQUE === null) { - PROCESS_UNIQUE = ByteUtils.randomBytes(5); - } - buffer2[4] = PROCESS_UNIQUE[0]; - buffer2[5] = PROCESS_UNIQUE[1]; - buffer2[6] = PROCESS_UNIQUE[2]; - buffer2[7] = PROCESS_UNIQUE[3]; - buffer2[8] = PROCESS_UNIQUE[4]; - buffer2[11] = inc & 255; - buffer2[10] = inc >> 8 & 255; - buffer2[9] = inc >> 16 & 255; - return buffer2; - } - toString(encoding) { - if (encoding === "base64") - return ByteUtils.toBase64(this.id); - if (encoding === "hex") - return this.toHexString(); - return this.toHexString(); - } - toJSON() { - return this.toHexString(); - } - static is(variable) { - return variable != null && typeof variable === "object" && "_bsontype" in variable && variable._bsontype === "ObjectId"; - } - equals(otherId) { - if (otherId === void 0 || otherId === null) { - return false; - } - if (_ObjectId.is(otherId)) { - return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]); - } - if (typeof otherId === "string") { - return otherId.toLowerCase() === this.toHexString(); - } - if (typeof otherId === "object" && typeof otherId.toHexString === "function") { - const otherIdString = otherId.toHexString(); - const thisIdString = this.toHexString(); - return typeof otherIdString === "string" && otherIdString.toLowerCase() === thisIdString; - } - return false; - } - getTimestamp() { - const timestamp = /* @__PURE__ */ new Date(); - const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false); - timestamp.setTime(Math.floor(time) * 1e3); - return timestamp; - } - static createPk() { - return new _ObjectId(); - } - static createFromTime(time) { - const buffer2 = ByteUtils.fromNumberArray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - BSONDataView.fromUint8Array(buffer2).setUint32(0, time, false); - return new _ObjectId(buffer2); - } - static createFromHexString(hexString) { - if (hexString?.length !== 24) { - throw new BSONError("hex string must be 24 characters"); - } - return new _ObjectId(ByteUtils.fromHex(hexString)); - } - static createFromBase64(base64) { - if (base64?.length !== 16) { - throw new BSONError("base64 string must be 16 characters"); - } - return new _ObjectId(ByteUtils.fromBase64(base64)); - } - static isValid(id) { - if (id == null) - return false; - try { - new _ObjectId(id); - return true; - } catch { - return false; - } - } - toExtendedJSON() { - if (this.toHexString) - return { $oid: this.toHexString() }; - return { $oid: this.toString("hex") }; - } - static fromExtendedJSON(doc) { - return new _ObjectId(doc.$oid); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - return `new ObjectId(${inspect(this.toHexString(), options)})`; - } - }; - ObjectId.index = Math.floor(Math.random() * 16777215); - function internalCalculateObjectSize(object, serializeFunctions, ignoreUndefined) { - let totalLength = 4 + 1; - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions, true, ignoreUndefined); - } - } else { - if (typeof object?.toBSON === "function") { - object = object.toBSON(); - } - for (const key of Object.keys(object)) { - totalLength += calculateElement(key, object[key], serializeFunctions, false, ignoreUndefined); - } - } - return totalLength; - } - function calculateElement(name, value, serializeFunctions = false, isArray = false, ignoreUndefined = false) { - if (typeof value?.toBSON === "function") { - value = value.toBSON(); - } - switch (typeof value) { - case "string": - return 1 + ByteUtils.utf8ByteLength(name) + 1 + 4 + ByteUtils.utf8ByteLength(value) + 1; - case "number": - if (Math.floor(value) === value && value >= JS_INT_MIN && value <= JS_INT_MAX) { - if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (4 + 1); - } else { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); - } - } else { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); - } - case "undefined": - if (isArray || !ignoreUndefined) - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1; - return 0; - case "boolean": - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 1); - case "object": - if (value != null && typeof value._bsontype === "string" && value[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } else if (value == null || value._bsontype === "MinKey" || value._bsontype === "MaxKey") { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1; - } else if (value._bsontype === "ObjectId") { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (12 + 1); - } else if (value instanceof Date || isDate(value)) { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); - } else if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || isAnyArrayBuffer(value)) { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 4 + 1) + value.byteLength; - } else if (value._bsontype === "Long" || value._bsontype === "Double" || value._bsontype === "Timestamp") { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); - } else if (value._bsontype === "Decimal128") { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (16 + 1); - } else if (value._bsontype === "Code") { - if (value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + 4 + ByteUtils.utf8ByteLength(value.code.toString()) + 1 + internalCalculateObjectSize(value.scope, serializeFunctions, ignoreUndefined); - } else { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + ByteUtils.utf8ByteLength(value.code.toString()) + 1; - } - } else if (value._bsontype === "Binary") { - const binary = value; - if (binary.sub_type === Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (binary.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (binary.position + 1 + 4 + 1); - } - } else if (value._bsontype === "Symbol") { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + ByteUtils.utf8ByteLength(value.value) + 4 + 1 + 1; - } else if (value._bsontype === "DBRef") { - const ordered_values = Object.assign({ - $ref: value.collection, - $id: value.oid - }, value.fields); - if (value.db != null) { - ordered_values["$db"] = value.db; - } - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + internalCalculateObjectSize(ordered_values, serializeFunctions, ignoreUndefined); - } else if (value instanceof RegExp || isRegExp(value)) { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + ByteUtils.utf8ByteLength(value.source) + 1 + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1; - } else if (value._bsontype === "BSONRegExp") { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + ByteUtils.utf8ByteLength(value.pattern) + 1 + ByteUtils.utf8ByteLength(value.options) + 1; - } else { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + internalCalculateObjectSize(value, serializeFunctions, ignoreUndefined) + 1; - } - case "function": - if (serializeFunctions) { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + ByteUtils.utf8ByteLength(value.toString()) + 1; - } - } - return 0; - } - function alphabetize(str) { - return str.split("").sort().join(""); - } - var BSONRegExp = class _BSONRegExp extends BSONValue { - get _bsontype() { - return "BSONRegExp"; - } - constructor(pattern, options) { - super(); - this.pattern = pattern; - this.options = alphabetize(options ?? ""); - if (this.pattern.indexOf("\0") !== -1) { - throw new BSONError(`BSON Regex patterns cannot contain null bytes, found: ${JSON.stringify(this.pattern)}`); - } - if (this.options.indexOf("\0") !== -1) { - throw new BSONError(`BSON Regex options cannot contain null bytes, found: ${JSON.stringify(this.options)}`); - } - for (let i = 0; i < this.options.length; i++) { - if (!(this.options[i] === "i" || this.options[i] === "m" || this.options[i] === "x" || this.options[i] === "l" || this.options[i] === "s" || this.options[i] === "u")) { - throw new BSONError(`The regular expression option [${this.options[i]}] is not supported`); - } - } - } - static parseOptions(options) { - return options ? options.split("").sort().join("") : ""; - } - toExtendedJSON(options) { - options = options || {}; - if (options.legacy) { - return { $regex: this.pattern, $options: this.options }; - } - return { $regularExpression: { pattern: this.pattern, options: this.options } }; - } - static fromExtendedJSON(doc) { - if ("$regex" in doc) { - if (typeof doc.$regex !== "string") { - if (doc.$regex._bsontype === "BSONRegExp") { - return doc; - } - } else { - return new _BSONRegExp(doc.$regex, _BSONRegExp.parseOptions(doc.$options)); - } - } - if ("$regularExpression" in doc) { - return new _BSONRegExp(doc.$regularExpression.pattern, _BSONRegExp.parseOptions(doc.$regularExpression.options)); - } - throw new BSONError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`); - } - inspect(depth, options, inspect) { - const stylize = getStylizeFunction(options) ?? ((v) => v); - inspect ??= defaultInspect; - const pattern = stylize(inspect(this.pattern), "regexp"); - const flags = stylize(inspect(this.options), "regexp"); - return `new BSONRegExp(${pattern}, ${flags})`; - } - }; - var BSONSymbol = class _BSONSymbol extends BSONValue { - get _bsontype() { - return "BSONSymbol"; - } - constructor(value) { - super(); - this.value = value; - } - valueOf() { - return this.value; - } - toString() { - return this.value; - } - toJSON() { - return this.value; - } - toExtendedJSON() { - return { $symbol: this.value }; - } - static fromExtendedJSON(doc) { - return new _BSONSymbol(doc.$symbol); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - return `new BSONSymbol(${inspect(this.value, options)})`; - } - }; - var LongWithoutOverridesClass = Long; - var Timestamp = class _Timestamp extends LongWithoutOverridesClass { - get _bsontype() { - return "Timestamp"; - } - constructor(low) { - if (low == null) { - super(0, 0, true); - } else if (typeof low === "bigint") { - super(low, true); - } else if (Long.isLong(low)) { - super(low.low, low.high, true); - } else if (typeof low === "object" && "t" in low && "i" in low) { - if (typeof low.t !== "number" && (typeof low.t !== "object" || low.t._bsontype !== "Int32")) { - throw new BSONError("Timestamp constructed from { t, i } must provide t as a number"); - } - if (typeof low.i !== "number" && (typeof low.i !== "object" || low.i._bsontype !== "Int32")) { - throw new BSONError("Timestamp constructed from { t, i } must provide i as a number"); - } - const t = Number(low.t); - const i = Number(low.i); - if (t < 0 || Number.isNaN(t)) { - throw new BSONError("Timestamp constructed from { t, i } must provide a positive t"); - } - if (i < 0 || Number.isNaN(i)) { - throw new BSONError("Timestamp constructed from { t, i } must provide a positive i"); - } - if (t > 4294967295) { - throw new BSONError("Timestamp constructed from { t, i } must provide t equal or less than uint32 max"); - } - if (i > 4294967295) { - throw new BSONError("Timestamp constructed from { t, i } must provide i equal or less than uint32 max"); - } - super(i, t, true); - } else { - throw new BSONError("A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }"); - } - } - toJSON() { - return { - $timestamp: this.toString() - }; - } - static fromInt(value) { - return new _Timestamp(Long.fromInt(value, true)); - } - static fromNumber(value) { - return new _Timestamp(Long.fromNumber(value, true)); - } - static fromBits(lowBits, highBits) { - return new _Timestamp({ i: lowBits, t: highBits }); - } - static fromString(str, optRadix) { - return new _Timestamp(Long.fromString(str, true, optRadix)); - } - toExtendedJSON() { - return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } }; - } - static fromExtendedJSON(doc) { - const i = Long.isLong(doc.$timestamp.i) ? doc.$timestamp.i.getLowBitsUnsigned() : doc.$timestamp.i; - const t = Long.isLong(doc.$timestamp.t) ? doc.$timestamp.t.getLowBitsUnsigned() : doc.$timestamp.t; - return new _Timestamp({ t, i }); - } - inspect(depth, options, inspect) { - inspect ??= defaultInspect; - const t = inspect(this.high >>> 0, options); - const i = inspect(this.low >>> 0, options); - return `new Timestamp({ t: ${t}, i: ${i} })`; - } - }; - Timestamp.MAX_VALUE = Long.MAX_UNSIGNED_VALUE; - var JS_INT_MAX_LONG = Long.fromNumber(JS_INT_MAX); - var JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN); - function internalDeserialize(buffer2, options, isArray) { - options = options == null ? {} : options; - const index = options && options.index ? options.index : 0; - const size = buffer2[index] | buffer2[index + 1] << 8 | buffer2[index + 2] << 16 | buffer2[index + 3] << 24; - if (size < 5) { - throw new BSONError(`bson size must be >= 5, is ${size}`); - } - if (options.allowObjectSmallerThanBufferSize && buffer2.length < size) { - throw new BSONError(`buffer length ${buffer2.length} must be >= bson size ${size}`); - } - if (!options.allowObjectSmallerThanBufferSize && buffer2.length !== size) { - throw new BSONError(`buffer length ${buffer2.length} must === bson size ${size}`); - } - if (size + index > buffer2.byteLength) { - throw new BSONError(`(bson size ${size} + options.index ${index} must be <= buffer length ${buffer2.byteLength})`); - } - if (buffer2[index + size - 1] !== 0) { - throw new BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00"); - } - return deserializeObject(buffer2, index, options, isArray); - } - var allowedDBRefKeys = /^\$ref$|^\$id$|^\$db$/; - function deserializeObject(buffer2, index, options, isArray = false) { - const fieldsAsRaw = options["fieldsAsRaw"] == null ? null : options["fieldsAsRaw"]; - const raw = options["raw"] == null ? false : options["raw"]; - const bsonRegExp = typeof options["bsonRegExp"] === "boolean" ? options["bsonRegExp"] : false; - const promoteBuffers = options.promoteBuffers ?? false; - const promoteLongs = options.promoteLongs ?? true; - const promoteValues = options.promoteValues ?? true; - const useBigInt64 = options.useBigInt64 ?? false; - if (useBigInt64 && !promoteValues) { - throw new BSONError("Must either request bigint or Long for int64 deserialization"); - } - if (useBigInt64 && !promoteLongs) { - throw new BSONError("Must either request bigint or Long for int64 deserialization"); - } - const validation = options.validation == null ? { utf8: true } : options.validation; - let globalUTFValidation = true; - let validationSetting; - const utf8KeysSet = /* @__PURE__ */ new Set(); - const utf8ValidatedKeys = validation.utf8; - if (typeof utf8ValidatedKeys === "boolean") { - validationSetting = utf8ValidatedKeys; - } else { - globalUTFValidation = false; - const utf8ValidationValues = Object.keys(utf8ValidatedKeys).map(function(key) { - return utf8ValidatedKeys[key]; - }); - if (utf8ValidationValues.length === 0) { - throw new BSONError("UTF-8 validation setting cannot be empty"); - } - if (typeof utf8ValidationValues[0] !== "boolean") { - throw new BSONError("Invalid UTF-8 validation option, must specify boolean values"); - } - validationSetting = utf8ValidationValues[0]; - if (!utf8ValidationValues.every((item) => item === validationSetting)) { - throw new BSONError("Invalid UTF-8 validation option - keys must be all true or all false"); - } - } - if (!globalUTFValidation) { - for (const key of Object.keys(utf8ValidatedKeys)) { - utf8KeysSet.add(key); - } - } - const startIndex = index; - if (buffer2.length < 5) - throw new BSONError("corrupt bson message < 5 bytes long"); - const size = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - if (size < 5 || size > buffer2.length) - throw new BSONError("corrupt bson message"); - const object = isArray ? [] : {}; - let arrayIndex = 0; - const done = false; - let isPossibleDBRef = isArray ? false : null; - const dataview = new DataView(buffer2.buffer, buffer2.byteOffset, buffer2.byteLength); - while (!done) { - const elementType = buffer2[index++]; - if (elementType === 0) - break; - let i = index; - while (buffer2[i] !== 0 && i < buffer2.length) { - i++; - } - if (i >= buffer2.byteLength) - throw new BSONError("Bad BSON Document: illegal CString"); - const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer2, index, i, false); - let shouldValidateKey = true; - if (globalUTFValidation || utf8KeysSet.has(name)) { - shouldValidateKey = validationSetting; - } else { - shouldValidateKey = !validationSetting; - } - if (isPossibleDBRef !== false && name[0] === "$") { - isPossibleDBRef = allowedDBRefKeys.test(name); - } - let value; - index = i + 1; - if (elementType === BSON_DATA_STRING) { - const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) { - throw new BSONError("bad string length in bson"); - } - value = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, shouldValidateKey); - index = index + stringSize; - } else if (elementType === BSON_DATA_OID) { - const oid = ByteUtils.allocate(12); - oid.set(buffer2.subarray(index, index + 12)); - value = new ObjectId(oid); - index = index + 12; - } else if (elementType === BSON_DATA_INT && promoteValues === false) { - value = new Int32(buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24); - } else if (elementType === BSON_DATA_INT) { - value = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - } else if (elementType === BSON_DATA_NUMBER && promoteValues === false) { - value = new Double(dataview.getFloat64(index, true)); - index = index + 8; - } else if (elementType === BSON_DATA_NUMBER) { - value = dataview.getFloat64(index, true); - index = index + 8; - } else if (elementType === BSON_DATA_DATE) { - const lowBits = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - const highBits = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - value = new Date(new Long(lowBits, highBits).toNumber()); - } else if (elementType === BSON_DATA_BOOLEAN) { - if (buffer2[index] !== 0 && buffer2[index] !== 1) - throw new BSONError("illegal boolean type value"); - value = buffer2[index++] === 1; - } else if (elementType === BSON_DATA_OBJECT) { - const _index = index; - const objectSize = buffer2[index] | buffer2[index + 1] << 8 | buffer2[index + 2] << 16 | buffer2[index + 3] << 24; - if (objectSize <= 0 || objectSize > buffer2.length - index) - throw new BSONError("bad embedded document length in bson"); - if (raw) { - value = buffer2.slice(index, index + objectSize); - } else { - let objectOptions = options; - if (!globalUTFValidation) { - objectOptions = { ...options, validation: { utf8: shouldValidateKey } }; - } - value = deserializeObject(buffer2, _index, objectOptions, false); - } - index = index + objectSize; - } else if (elementType === BSON_DATA_ARRAY) { - const _index = index; - const objectSize = buffer2[index] | buffer2[index + 1] << 8 | buffer2[index + 2] << 16 | buffer2[index + 3] << 24; - let arrayOptions = options; - const stopIndex = index + objectSize; - if (fieldsAsRaw && fieldsAsRaw[name]) { - arrayOptions = { ...options, raw: true }; - } - if (!globalUTFValidation) { - arrayOptions = { ...arrayOptions, validation: { utf8: shouldValidateKey } }; - } - value = deserializeObject(buffer2, _index, arrayOptions, true); - index = index + objectSize; - if (buffer2[index - 1] !== 0) - throw new BSONError("invalid array terminator byte"); - if (index !== stopIndex) - throw new BSONError("corrupted array bson"); - } else if (elementType === BSON_DATA_UNDEFINED) { - value = void 0; - } else if (elementType === BSON_DATA_NULL) { - value = null; - } else if (elementType === BSON_DATA_LONG) { - const dataview2 = BSONDataView.fromUint8Array(buffer2.subarray(index, index + 8)); - const lowBits = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - const highBits = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - const long = new Long(lowBits, highBits); - if (useBigInt64) { - value = dataview2.getBigInt64(0, true); - } else if (promoteLongs && promoteValues === true) { - value = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - } else { - value = long; - } - } else if (elementType === BSON_DATA_DECIMAL128) { - const bytes = ByteUtils.allocate(16); - bytes.set(buffer2.subarray(index, index + 16), 0); - index = index + 16; - value = new Decimal128(bytes); - } else if (elementType === BSON_DATA_BINARY) { - let binarySize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - const totalBinarySize = binarySize; - const subType = buffer2[index++]; - if (binarySize < 0) - throw new BSONError("Negative binary type element size found"); - if (binarySize > buffer2.byteLength) - throw new BSONError("Binary type size larger than document size"); - if (buffer2["slice"] != null) { - if (subType === Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - if (binarySize < 0) - throw new BSONError("Negative binary type element size found for subtype 0x02"); - if (binarySize > totalBinarySize - 4) - throw new BSONError("Binary type with subtype 0x02 contains too long binary size"); - if (binarySize < totalBinarySize - 4) - throw new BSONError("Binary type with subtype 0x02 contains too short binary size"); - } - if (promoteBuffers && promoteValues) { - value = ByteUtils.toLocalBufferType(buffer2.slice(index, index + binarySize)); - } else { - value = new Binary(buffer2.slice(index, index + binarySize), subType); - if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) { - value = value.toUUID(); - } - } - } else { - const _buffer = ByteUtils.allocate(binarySize); - if (subType === Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - if (binarySize < 0) - throw new BSONError("Negative binary type element size found for subtype 0x02"); - if (binarySize > totalBinarySize - 4) - throw new BSONError("Binary type with subtype 0x02 contains too long binary size"); - if (binarySize < totalBinarySize - 4) - throw new BSONError("Binary type with subtype 0x02 contains too short binary size"); - } - for (i = 0; i < binarySize; i++) { - _buffer[i] = buffer2[index + i]; - } - if (promoteBuffers && promoteValues) { - value = _buffer; - } else { - value = new Binary(buffer2.slice(index, index + binarySize), subType); - if (subType === BSON_BINARY_SUBTYPE_UUID_NEW && UUID.isValid(value)) { - value = value.toUUID(); - } - } - } - index = index + binarySize; - } else if (elementType === BSON_DATA_REGEXP && bsonRegExp === false) { - i = index; - while (buffer2[i] !== 0 && i < buffer2.length) { - i++; - } - if (i >= buffer2.length) - throw new BSONError("Bad BSON Document: illegal CString"); - const source = ByteUtils.toUTF8(buffer2, index, i, false); - index = i + 1; - i = index; - while (buffer2[i] !== 0 && i < buffer2.length) { - i++; - } - if (i >= buffer2.length) - throw new BSONError("Bad BSON Document: illegal CString"); - const regExpOptions = ByteUtils.toUTF8(buffer2, index, i, false); - index = i + 1; - const optionsArray = new Array(regExpOptions.length); - for (i = 0; i < regExpOptions.length; i++) { - switch (regExpOptions[i]) { - case "m": - optionsArray[i] = "m"; - break; - case "s": - optionsArray[i] = "g"; - break; - case "i": - optionsArray[i] = "i"; - break; - } - } - value = new RegExp(source, optionsArray.join("")); - } else if (elementType === BSON_DATA_REGEXP && bsonRegExp === true) { - i = index; - while (buffer2[i] !== 0 && i < buffer2.length) { - i++; - } - if (i >= buffer2.length) - throw new BSONError("Bad BSON Document: illegal CString"); - const source = ByteUtils.toUTF8(buffer2, index, i, false); - index = i + 1; - i = index; - while (buffer2[i] !== 0 && i < buffer2.length) { - i++; - } - if (i >= buffer2.length) - throw new BSONError("Bad BSON Document: illegal CString"); - const regExpOptions = ByteUtils.toUTF8(buffer2, index, i, false); - index = i + 1; - value = new BSONRegExp(source, regExpOptions); - } else if (elementType === BSON_DATA_SYMBOL) { - const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) { - throw new BSONError("bad string length in bson"); - } - const symbol = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, shouldValidateKey); - value = promoteValues ? symbol : new BSONSymbol(symbol); - index = index + stringSize; - } else if (elementType === BSON_DATA_TIMESTAMP) { - const i2 = buffer2[index++] + buffer2[index++] * (1 << 8) + buffer2[index++] * (1 << 16) + buffer2[index++] * (1 << 24); - const t = buffer2[index++] + buffer2[index++] * (1 << 8) + buffer2[index++] * (1 << 16) + buffer2[index++] * (1 << 24); - value = new Timestamp({ i: i2, t }); - } else if (elementType === BSON_DATA_MIN_KEY) { - value = new MinKey(); - } else if (elementType === BSON_DATA_MAX_KEY) { - value = new MaxKey(); - } else if (elementType === BSON_DATA_CODE) { - const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) { - throw new BSONError("bad string length in bson"); - } - const functionString = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, shouldValidateKey); - value = new Code(functionString); - index = index + stringSize; - } else if (elementType === BSON_DATA_CODE_W_SCOPE) { - const totalSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - if (totalSize < 4 + 4 + 4 + 1) { - throw new BSONError("code_w_scope total size shorter minimum expected length"); - } - const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) { - throw new BSONError("bad string length in bson"); - } - const functionString = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, shouldValidateKey); - index = index + stringSize; - const _index = index; - const objectSize = buffer2[index] | buffer2[index + 1] << 8 | buffer2[index + 2] << 16 | buffer2[index + 3] << 24; - const scopeObject = deserializeObject(buffer2, _index, options, false); - index = index + objectSize; - if (totalSize < 4 + 4 + objectSize + stringSize) { - throw new BSONError("code_w_scope total size is too short, truncating scope"); - } - if (totalSize > 4 + 4 + objectSize + stringSize) { - throw new BSONError("code_w_scope total size is too long, clips outer document"); - } - value = new Code(functionString, scopeObject); - } else if (elementType === BSON_DATA_DBPOINTER) { - const stringSize = buffer2[index++] | buffer2[index++] << 8 | buffer2[index++] << 16 | buffer2[index++] << 24; - if (stringSize <= 0 || stringSize > buffer2.length - index || buffer2[index + stringSize - 1] !== 0) - throw new BSONError("bad string length in bson"); - if (validation != null && validation.utf8) { - if (!validateUtf8(buffer2, index, index + stringSize - 1)) { - throw new BSONError("Invalid UTF-8 string in BSON document"); - } - } - const namespace = ByteUtils.toUTF8(buffer2, index, index + stringSize - 1, false); - index = index + stringSize; - const oidBuffer = ByteUtils.allocate(12); - oidBuffer.set(buffer2.subarray(index, index + 12), 0); - const oid = new ObjectId(oidBuffer); - index = index + 12; - value = new DBRef(namespace, oid); - } else { - throw new BSONError(`Detected unknown BSON type ${elementType.toString(16)} for fieldname "${name}"`); - } - if (name === "__proto__") { - Object.defineProperty(object, name, { - value, - writable: true, - enumerable: true, - configurable: true - }); - } else { - object[name] = value; - } - } - if (size !== index - startIndex) { - if (isArray) - throw new BSONError("corrupt array bson"); - throw new BSONError("corrupt object bson"); - } - if (!isPossibleDBRef) - return object; - if (isDBRefLike(object)) { - const copy = Object.assign({}, object); - delete copy.$ref; - delete copy.$id; - delete copy.$db; - return new DBRef(object.$ref, object.$id, object.$db, copy); - } - return object; - } - var regexp = /\x00/; - var ignoreKeys = /* @__PURE__ */ new Set(["$db", "$ref", "$id", "$clusterTime"]); - function serializeString(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_STRING; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes + 1; - buffer2[index - 1] = 0; - const size = ByteUtils.encodeUTF8Into(buffer2, value, index + 4); - buffer2[index + 3] = size + 1 >> 24 & 255; - buffer2[index + 2] = size + 1 >> 16 & 255; - buffer2[index + 1] = size + 1 >> 8 & 255; - buffer2[index] = size + 1 & 255; - index = index + 4 + size; - buffer2[index++] = 0; - return index; - } - var NUMBER_SPACE = new DataView(new ArrayBuffer(8), 0, 8); - var FOUR_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 4); - var EIGHT_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 8); - function serializeNumber(buffer2, key, value, index) { - const isNegativeZero = Object.is(value, -0); - const type = !isNegativeZero && Number.isSafeInteger(value) && value <= BSON_INT32_MAX && value >= BSON_INT32_MIN ? BSON_DATA_INT : BSON_DATA_NUMBER; - if (type === BSON_DATA_INT) { - NUMBER_SPACE.setInt32(0, value, true); - } else { - NUMBER_SPACE.setFloat64(0, value, true); - } - const bytes = type === BSON_DATA_INT ? FOUR_BYTE_VIEW_ON_NUMBER : EIGHT_BYTE_VIEW_ON_NUMBER; - buffer2[index++] = type; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - buffer2.set(bytes, index); - index += bytes.byteLength; - return index; - } - function serializeBigInt(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_LONG; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index += numberOfWrittenBytes; - buffer2[index++] = 0; - NUMBER_SPACE.setBigInt64(0, value, true); - buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER, index); - index += EIGHT_BYTE_VIEW_ON_NUMBER.byteLength; - return index; - } - function serializeNull(buffer2, key, _, index) { - buffer2[index++] = BSON_DATA_NULL; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - return index; - } - function serializeBoolean(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_BOOLEAN; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - buffer2[index++] = value ? 1 : 0; - return index; - } - function serializeDate(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_DATE; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - const dateInMilis = Long.fromNumber(value.getTime()); - const lowBits = dateInMilis.getLowBits(); - const highBits = dateInMilis.getHighBits(); - buffer2[index++] = lowBits & 255; - buffer2[index++] = lowBits >> 8 & 255; - buffer2[index++] = lowBits >> 16 & 255; - buffer2[index++] = lowBits >> 24 & 255; - buffer2[index++] = highBits & 255; - buffer2[index++] = highBits >> 8 & 255; - buffer2[index++] = highBits >> 16 & 255; - buffer2[index++] = highBits >> 24 & 255; - return index; - } - function serializeRegExp(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_REGEXP; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - if (value.source && value.source.match(regexp) != null) { - throw new BSONError("value " + value.source + " must not contain null bytes"); - } - index = index + ByteUtils.encodeUTF8Into(buffer2, value.source, index); - buffer2[index++] = 0; - if (value.ignoreCase) - buffer2[index++] = 105; - if (value.global) - buffer2[index++] = 115; - if (value.multiline) - buffer2[index++] = 109; - buffer2[index++] = 0; - return index; - } - function serializeBSONRegExp(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_REGEXP; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - if (value.pattern.match(regexp) != null) { - throw new BSONError("pattern " + value.pattern + " must not contain null bytes"); - } - index = index + ByteUtils.encodeUTF8Into(buffer2, value.pattern, index); - buffer2[index++] = 0; - const sortedOptions = value.options.split("").sort().join(""); - index = index + ByteUtils.encodeUTF8Into(buffer2, sortedOptions, index); - buffer2[index++] = 0; - return index; - } - function serializeMinMax(buffer2, key, value, index) { - if (value === null) { - buffer2[index++] = BSON_DATA_NULL; - } else if (value._bsontype === "MinKey") { - buffer2[index++] = BSON_DATA_MIN_KEY; - } else { - buffer2[index++] = BSON_DATA_MAX_KEY; - } - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - return index; - } - function serializeObjectId(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_OID; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - const idValue = value.id; - if (isUint8Array(idValue)) { - for (let i = 0; i < 12; i++) { - buffer2[index++] = idValue[i]; - } - } else { - throw new BSONError("object [" + JSON.stringify(value) + "] is not a valid ObjectId"); - } - return index; - } - function serializeBuffer(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_BINARY; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - const size = value.length; - buffer2[index++] = size & 255; - buffer2[index++] = size >> 8 & 255; - buffer2[index++] = size >> 16 & 255; - buffer2[index++] = size >> 24 & 255; - buffer2[index++] = BSON_BINARY_SUBTYPE_DEFAULT; - buffer2.set(value, index); - index = index + size; - return index; - } - function serializeObject(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path) { - if (path.has(value)) { - throw new BSONError("Cannot convert circular structure to BSON"); - } - path.add(value); - buffer2[index++] = Array.isArray(value) ? BSON_DATA_ARRAY : BSON_DATA_OBJECT; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - const endIndex = serializeInto(buffer2, value, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path); - path.delete(value); - return endIndex; - } - function serializeDecimal128(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_DECIMAL128; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - buffer2.set(value.bytes.subarray(0, 16), index); - return index + 16; - } - function serializeLong(buffer2, key, value, index) { - buffer2[index++] = value._bsontype === "Long" ? BSON_DATA_LONG : BSON_DATA_TIMESTAMP; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - const lowBits = value.getLowBits(); - const highBits = value.getHighBits(); - buffer2[index++] = lowBits & 255; - buffer2[index++] = lowBits >> 8 & 255; - buffer2[index++] = lowBits >> 16 & 255; - buffer2[index++] = lowBits >> 24 & 255; - buffer2[index++] = highBits & 255; - buffer2[index++] = highBits >> 8 & 255; - buffer2[index++] = highBits >> 16 & 255; - buffer2[index++] = highBits >> 24 & 255; - return index; - } - function serializeInt32(buffer2, key, value, index) { - value = value.valueOf(); - buffer2[index++] = BSON_DATA_INT; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - buffer2[index++] = value & 255; - buffer2[index++] = value >> 8 & 255; - buffer2[index++] = value >> 16 & 255; - buffer2[index++] = value >> 24 & 255; - return index; - } - function serializeDouble(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_NUMBER; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - NUMBER_SPACE.setFloat64(0, value.value, true); - buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER, index); - index = index + 8; - return index; - } - function serializeFunction(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_CODE; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - const functionString = value.toString(); - const size = ByteUtils.encodeUTF8Into(buffer2, functionString, index + 4) + 1; - buffer2[index] = size & 255; - buffer2[index + 1] = size >> 8 & 255; - buffer2[index + 2] = size >> 16 & 255; - buffer2[index + 3] = size >> 24 & 255; - index = index + 4 + size - 1; - buffer2[index++] = 0; - return index; - } - function serializeCode(buffer2, key, value, index, checkKeys = false, depth = 0, serializeFunctions = false, ignoreUndefined = true, path) { - if (value.scope && typeof value.scope === "object") { - buffer2[index++] = BSON_DATA_CODE_W_SCOPE; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - let startIndex = index; - const functionString = value.code; - index = index + 4; - const codeSize = ByteUtils.encodeUTF8Into(buffer2, functionString, index + 4) + 1; - buffer2[index] = codeSize & 255; - buffer2[index + 1] = codeSize >> 8 & 255; - buffer2[index + 2] = codeSize >> 16 & 255; - buffer2[index + 3] = codeSize >> 24 & 255; - buffer2[index + 4 + codeSize - 1] = 0; - index = index + codeSize + 4; - const endIndex = serializeInto(buffer2, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path); - index = endIndex - 1; - const totalSize = endIndex - startIndex; - buffer2[startIndex++] = totalSize & 255; - buffer2[startIndex++] = totalSize >> 8 & 255; - buffer2[startIndex++] = totalSize >> 16 & 255; - buffer2[startIndex++] = totalSize >> 24 & 255; - buffer2[index++] = 0; - } else { - buffer2[index++] = BSON_DATA_CODE; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - const functionString = value.code.toString(); - const size = ByteUtils.encodeUTF8Into(buffer2, functionString, index + 4) + 1; - buffer2[index] = size & 255; - buffer2[index + 1] = size >> 8 & 255; - buffer2[index + 2] = size >> 16 & 255; - buffer2[index + 3] = size >> 24 & 255; - index = index + 4 + size - 1; - buffer2[index++] = 0; - } - return index; - } - function serializeBinary(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_BINARY; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - const data = value.buffer; - let size = value.position; - if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) - size = size + 4; - buffer2[index++] = size & 255; - buffer2[index++] = size >> 8 & 255; - buffer2[index++] = size >> 16 & 255; - buffer2[index++] = size >> 24 & 255; - buffer2[index++] = value.sub_type; - if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) { - size = size - 4; - buffer2[index++] = size & 255; - buffer2[index++] = size >> 8 & 255; - buffer2[index++] = size >> 16 & 255; - buffer2[index++] = size >> 24 & 255; - } - buffer2.set(data, index); - index = index + value.position; - return index; - } - function serializeSymbol(buffer2, key, value, index) { - buffer2[index++] = BSON_DATA_SYMBOL; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - const size = ByteUtils.encodeUTF8Into(buffer2, value.value, index + 4) + 1; - buffer2[index] = size & 255; - buffer2[index + 1] = size >> 8 & 255; - buffer2[index + 2] = size >> 16 & 255; - buffer2[index + 3] = size >> 24 & 255; - index = index + 4 + size - 1; - buffer2[index++] = 0; - return index; - } - function serializeDBRef(buffer2, key, value, index, depth, serializeFunctions, path) { - buffer2[index++] = BSON_DATA_OBJECT; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer2, key, index); - index = index + numberOfWrittenBytes; - buffer2[index++] = 0; - let startIndex = index; - let output = { - $ref: value.collection || value.namespace, - $id: value.oid - }; - if (value.db != null) { - output.$db = value.db; - } - output = Object.assign(output, value.fields); - const endIndex = serializeInto(buffer2, output, false, index, depth + 1, serializeFunctions, true, path); - const size = endIndex - startIndex; - buffer2[startIndex++] = size & 255; - buffer2[startIndex++] = size >> 8 & 255; - buffer2[startIndex++] = size >> 16 & 255; - buffer2[startIndex++] = size >> 24 & 255; - return endIndex; - } - function serializeInto(buffer2, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) { - if (path == null) { - if (object == null) { - buffer2[0] = 5; - buffer2[1] = 0; - buffer2[2] = 0; - buffer2[3] = 0; - buffer2[4] = 0; - return 5; - } - if (Array.isArray(object)) { - throw new BSONError("serialize does not support an array as the root input"); - } - if (typeof object !== "object") { - throw new BSONError("serialize does not support non-object as the root input"); - } else if ("_bsontype" in object && typeof object._bsontype === "string") { - throw new BSONError(`BSON types cannot be serialized as a document`); - } else if (isDate(object) || isRegExp(object) || isUint8Array(object) || isAnyArrayBuffer(object)) { - throw new BSONError(`date, regexp, typedarray, and arraybuffer cannot be BSON documents`); - } - path = /* @__PURE__ */ new Set(); - } - path.add(object); - let index = startingIndex + 4; - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - const key = `${i}`; - let value = object[i]; - if (typeof value?.toBSON === "function") { - value = value.toBSON(); - } - if (typeof value === "string") { - index = serializeString(buffer2, key, value, index); - } else if (typeof value === "number") { - index = serializeNumber(buffer2, key, value, index); - } else if (typeof value === "bigint") { - index = serializeBigInt(buffer2, key, value, index); - } else if (typeof value === "boolean") { - index = serializeBoolean(buffer2, key, value, index); - } else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer2, key, value, index); - } else if (value === void 0) { - index = serializeNull(buffer2, key, value, index); - } else if (value === null) { - index = serializeNull(buffer2, key, value, index); - } else if (isUint8Array(value)) { - index = serializeBuffer(buffer2, key, value, index); - } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer2, key, value, index); - } else if (typeof value === "object" && value._bsontype == null) { - index = serializeObject(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } else if (typeof value === "object" && value[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } else if (value._bsontype === "ObjectId") { - index = serializeObjectId(buffer2, key, value, index); - } else if (value._bsontype === "Decimal128") { - index = serializeDecimal128(buffer2, key, value, index); - } else if (value._bsontype === "Long" || value._bsontype === "Timestamp") { - index = serializeLong(buffer2, key, value, index); - } else if (value._bsontype === "Double") { - index = serializeDouble(buffer2, key, value, index); - } else if (typeof value === "function" && serializeFunctions) { - index = serializeFunction(buffer2, key, value, index); - } else if (value._bsontype === "Code") { - index = serializeCode(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } else if (value._bsontype === "Binary") { - index = serializeBinary(buffer2, key, value, index); - } else if (value._bsontype === "BSONSymbol") { - index = serializeSymbol(buffer2, key, value, index); - } else if (value._bsontype === "DBRef") { - index = serializeDBRef(buffer2, key, value, index, depth, serializeFunctions, path); - } else if (value._bsontype === "BSONRegExp") { - index = serializeBSONRegExp(buffer2, key, value, index); - } else if (value._bsontype === "Int32") { - index = serializeInt32(buffer2, key, value, index); - } else if (value._bsontype === "MinKey" || value._bsontype === "MaxKey") { - index = serializeMinMax(buffer2, key, value, index); - } else if (typeof value._bsontype !== "undefined") { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); - } - } - } else if (object instanceof Map || isMap(object)) { - const iterator = object.entries(); - let done = false; - while (!done) { - const entry = iterator.next(); - done = !!entry.done; - if (done) - continue; - const key = entry.value[0]; - let value = entry.value[1]; - if (typeof value?.toBSON === "function") { - value = value.toBSON(); - } - const type = typeof value; - if (typeof key === "string" && !ignoreKeys.has(key)) { - if (key.match(regexp) != null) { - throw new BSONError("key " + key + " must not contain null bytes"); - } - if (checkKeys) { - if ("$" === key[0]) { - throw new BSONError("key " + key + " must not start with '$'"); - } else if (~key.indexOf(".")) { - throw new BSONError("key " + key + " must not contain '.'"); - } - } - } - if (type === "string") { - index = serializeString(buffer2, key, value, index); - } else if (type === "number") { - index = serializeNumber(buffer2, key, value, index); - } else if (type === "bigint") { - index = serializeBigInt(buffer2, key, value, index); - } else if (type === "boolean") { - index = serializeBoolean(buffer2, key, value, index); - } else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer2, key, value, index); - } else if (value === null || value === void 0 && ignoreUndefined === false) { - index = serializeNull(buffer2, key, value, index); - } else if (isUint8Array(value)) { - index = serializeBuffer(buffer2, key, value, index); - } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer2, key, value, index); - } else if (type === "object" && value._bsontype == null) { - index = serializeObject(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } else if (typeof value === "object" && value[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } else if (value._bsontype === "ObjectId") { - index = serializeObjectId(buffer2, key, value, index); - } else if (type === "object" && value._bsontype === "Decimal128") { - index = serializeDecimal128(buffer2, key, value, index); - } else if (value._bsontype === "Long" || value._bsontype === "Timestamp") { - index = serializeLong(buffer2, key, value, index); - } else if (value._bsontype === "Double") { - index = serializeDouble(buffer2, key, value, index); - } else if (value._bsontype === "Code") { - index = serializeCode(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } else if (typeof value === "function" && serializeFunctions) { - index = serializeFunction(buffer2, key, value, index); - } else if (value._bsontype === "Binary") { - index = serializeBinary(buffer2, key, value, index); - } else if (value._bsontype === "BSONSymbol") { - index = serializeSymbol(buffer2, key, value, index); - } else if (value._bsontype === "DBRef") { - index = serializeDBRef(buffer2, key, value, index, depth, serializeFunctions, path); - } else if (value._bsontype === "BSONRegExp") { - index = serializeBSONRegExp(buffer2, key, value, index); - } else if (value._bsontype === "Int32") { - index = serializeInt32(buffer2, key, value, index); - } else if (value._bsontype === "MinKey" || value._bsontype === "MaxKey") { - index = serializeMinMax(buffer2, key, value, index); - } else if (typeof value._bsontype !== "undefined") { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); - } - } - } else { - if (typeof object?.toBSON === "function") { - object = object.toBSON(); - if (object != null && typeof object !== "object") { - throw new BSONError("toBSON function did not return an object"); - } - } - for (const key of Object.keys(object)) { - let value = object[key]; - if (typeof value?.toBSON === "function") { - value = value.toBSON(); - } - const type = typeof value; - if (typeof key === "string" && !ignoreKeys.has(key)) { - if (key.match(regexp) != null) { - throw new BSONError("key " + key + " must not contain null bytes"); - } - if (checkKeys) { - if ("$" === key[0]) { - throw new BSONError("key " + key + " must not start with '$'"); - } else if (~key.indexOf(".")) { - throw new BSONError("key " + key + " must not contain '.'"); - } - } - } - if (type === "string") { - index = serializeString(buffer2, key, value, index); - } else if (type === "number") { - index = serializeNumber(buffer2, key, value, index); - } else if (type === "bigint") { - index = serializeBigInt(buffer2, key, value, index); - } else if (type === "boolean") { - index = serializeBoolean(buffer2, key, value, index); - } else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer2, key, value, index); - } else if (value === void 0) { - if (ignoreUndefined === false) - index = serializeNull(buffer2, key, value, index); - } else if (value === null) { - index = serializeNull(buffer2, key, value, index); - } else if (isUint8Array(value)) { - index = serializeBuffer(buffer2, key, value, index); - } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer2, key, value, index); - } else if (type === "object" && value._bsontype == null) { - index = serializeObject(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } else if (typeof value === "object" && value[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } else if (value._bsontype === "ObjectId") { - index = serializeObjectId(buffer2, key, value, index); - } else if (type === "object" && value._bsontype === "Decimal128") { - index = serializeDecimal128(buffer2, key, value, index); - } else if (value._bsontype === "Long" || value._bsontype === "Timestamp") { - index = serializeLong(buffer2, key, value, index); - } else if (value._bsontype === "Double") { - index = serializeDouble(buffer2, key, value, index); - } else if (value._bsontype === "Code") { - index = serializeCode(buffer2, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } else if (typeof value === "function" && serializeFunctions) { - index = serializeFunction(buffer2, key, value, index); - } else if (value._bsontype === "Binary") { - index = serializeBinary(buffer2, key, value, index); - } else if (value._bsontype === "BSONSymbol") { - index = serializeSymbol(buffer2, key, value, index); - } else if (value._bsontype === "DBRef") { - index = serializeDBRef(buffer2, key, value, index, depth, serializeFunctions, path); - } else if (value._bsontype === "BSONRegExp") { - index = serializeBSONRegExp(buffer2, key, value, index); - } else if (value._bsontype === "Int32") { - index = serializeInt32(buffer2, key, value, index); - } else if (value._bsontype === "MinKey" || value._bsontype === "MaxKey") { - index = serializeMinMax(buffer2, key, value, index); - } else if (typeof value._bsontype !== "undefined") { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); - } - } - } - path.delete(object); - buffer2[index++] = 0; - const size = index - startingIndex; - buffer2[startingIndex++] = size & 255; - buffer2[startingIndex++] = size >> 8 & 255; - buffer2[startingIndex++] = size >> 16 & 255; - buffer2[startingIndex++] = size >> 24 & 255; - return index; - } - function isBSONType(value) { - return value != null && typeof value === "object" && "_bsontype" in value && typeof value._bsontype === "string"; - } - var keysToCodecs = { - $oid: ObjectId, - $binary: Binary, - $uuid: Binary, - $symbol: BSONSymbol, - $numberInt: Int32, - $numberDecimal: Decimal128, - $numberDouble: Double, - $numberLong: Long, - $minKey: MinKey, - $maxKey: MaxKey, - $regex: BSONRegExp, - $regularExpression: BSONRegExp, - $timestamp: Timestamp - }; - function deserializeValue(value, options = {}) { - if (typeof value === "number") { - const in32BitRange = value <= BSON_INT32_MAX && value >= BSON_INT32_MIN; - const in64BitRange = value <= BSON_INT64_MAX && value >= BSON_INT64_MIN; - if (options.relaxed || options.legacy) { - return value; - } - if (Number.isInteger(value) && !Object.is(value, -0)) { - if (in32BitRange) { - return new Int32(value); - } - if (in64BitRange) { - if (options.useBigInt64) { - return BigInt(value); - } - return Long.fromNumber(value); - } - } - return new Double(value); - } - if (value == null || typeof value !== "object") - return value; - if (value.$undefined) - return null; - const keys = Object.keys(value).filter((k) => k.startsWith("$") && value[k] != null); - for (let i = 0; i < keys.length; i++) { - const c = keysToCodecs[keys[i]]; - if (c) - return c.fromExtendedJSON(value, options); - } - if (value.$date != null) { - const d = value.$date; - const date = /* @__PURE__ */ new Date(); - if (options.legacy) { - if (typeof d === "number") - date.setTime(d); - else if (typeof d === "string") - date.setTime(Date.parse(d)); - else if (typeof d === "bigint") - date.setTime(Number(d)); - else - throw new BSONRuntimeError(`Unrecognized type for EJSON date: ${typeof d}`); - } else { - if (typeof d === "string") - date.setTime(Date.parse(d)); - else if (Long.isLong(d)) - date.setTime(d.toNumber()); - else if (typeof d === "number" && options.relaxed) - date.setTime(d); - else if (typeof d === "bigint") - date.setTime(Number(d)); - else - throw new BSONRuntimeError(`Unrecognized type for EJSON date: ${typeof d}`); - } - return date; - } - if (value.$code != null) { - const copy = Object.assign({}, value); - if (value.$scope) { - copy.$scope = deserializeValue(value.$scope); - } - return Code.fromExtendedJSON(value); - } - if (isDBRefLike(value) || value.$dbPointer) { - const v = value.$ref ? value : value.$dbPointer; - if (v instanceof DBRef) - return v; - const dollarKeys = Object.keys(v).filter((k) => k.startsWith("$")); - let valid = true; - dollarKeys.forEach((k) => { - if (["$ref", "$id", "$db"].indexOf(k) === -1) - valid = false; - }); - if (valid) - return DBRef.fromExtendedJSON(v); - } - return value; - } - function serializeArray(array, options) { - return array.map((v, index) => { - options.seenObjects.push({ propertyName: `index ${index}`, obj: null }); - try { - return serializeValue(v, options); - } finally { - options.seenObjects.pop(); - } - }); - } - function getISOString(date) { - const isoStr = date.toISOString(); - return date.getUTCMilliseconds() !== 0 ? isoStr : isoStr.slice(0, -5) + "Z"; - } - function serializeValue(value, options) { - if (value instanceof Map || isMap(value)) { - const obj = /* @__PURE__ */ Object.create(null); - for (const [k, v] of value) { - if (typeof k !== "string") { - throw new BSONError("Can only serialize maps with string keys"); - } - obj[k] = v; - } - return serializeValue(obj, options); - } - if ((typeof value === "object" || typeof value === "function") && value !== null) { - const index = options.seenObjects.findIndex((entry) => entry.obj === value); - if (index !== -1) { - const props = options.seenObjects.map((entry) => entry.propertyName); - const leadingPart = props.slice(0, index).map((prop) => `${prop} -> `).join(""); - const alreadySeen = props[index]; - const circularPart = " -> " + props.slice(index + 1, props.length - 1).map((prop) => `${prop} -> `).join(""); - const current = props[props.length - 1]; - const leadingSpace = " ".repeat(leadingPart.length + alreadySeen.length / 2); - const dashes = "-".repeat(circularPart.length + (alreadySeen.length + current.length) / 2 - 1); - throw new BSONError(`Converting circular structure to EJSON: - ${leadingPart}${alreadySeen}${circularPart}${current} - ${leadingSpace}\\${dashes}/`); - } - options.seenObjects[options.seenObjects.length - 1].obj = value; - } - if (Array.isArray(value)) - return serializeArray(value, options); - if (value === void 0) - return null; - if (value instanceof Date || isDate(value)) { - const dateNum = value.getTime(), inRange = dateNum > -1 && dateNum < 2534023188e5; - if (options.legacy) { - return options.relaxed && inRange ? { $date: value.getTime() } : { $date: getISOString(value) }; - } - return options.relaxed && inRange ? { $date: getISOString(value) } : { $date: { $numberLong: value.getTime().toString() } }; - } - if (typeof value === "number" && (!options.relaxed || !isFinite(value))) { - if (Number.isInteger(value) && !Object.is(value, -0)) { - if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) { - return { $numberInt: value.toString() }; - } - if (value >= BSON_INT64_MIN && value <= BSON_INT64_MAX) { - return { $numberLong: value.toString() }; - } - } - return { $numberDouble: Object.is(value, -0) ? "-0.0" : value.toString() }; - } - if (typeof value === "bigint") { - if (!options.relaxed) { - return { $numberLong: BigInt.asIntN(64, value).toString() }; - } - return Number(BigInt.asIntN(64, value)); - } - if (value instanceof RegExp || isRegExp(value)) { - let flags = value.flags; - if (flags === void 0) { - const match = value.toString().match(/[gimuy]*$/); - if (match) { - flags = match[0]; - } - } - const rx = new BSONRegExp(value.source, flags); - return rx.toExtendedJSON(options); - } - if (value != null && typeof value === "object") - return serializeDocument(value, options); - return value; - } - var BSON_TYPE_MAPPINGS = { - Binary: (o) => new Binary(o.value(), o.sub_type), - Code: (o) => new Code(o.code, o.scope), - DBRef: (o) => new DBRef(o.collection || o.namespace, o.oid, o.db, o.fields), - Decimal128: (o) => new Decimal128(o.bytes), - Double: (o) => new Double(o.value), - Int32: (o) => new Int32(o.value), - Long: (o) => Long.fromBits(o.low != null ? o.low : o.low_, o.low != null ? o.high : o.high_, o.low != null ? o.unsigned : o.unsigned_), - MaxKey: () => new MaxKey(), - MinKey: () => new MinKey(), - ObjectId: (o) => new ObjectId(o), - BSONRegExp: (o) => new BSONRegExp(o.pattern, o.options), - BSONSymbol: (o) => new BSONSymbol(o.value), - Timestamp: (o) => Timestamp.fromBits(o.low, o.high) - }; - function serializeDocument(doc, options) { - if (doc == null || typeof doc !== "object") - throw new BSONError("not an object instance"); - const bsontype = doc._bsontype; - if (typeof bsontype === "undefined") { - const _doc = {}; - for (const name of Object.keys(doc)) { - options.seenObjects.push({ propertyName: name, obj: null }); - try { - const value = serializeValue(doc[name], options); - if (name === "__proto__") { - Object.defineProperty(_doc, name, { - value, - writable: true, - enumerable: true, - configurable: true - }); - } else { - _doc[name] = value; - } - } finally { - options.seenObjects.pop(); - } - } - return _doc; - } else if (doc != null && typeof doc === "object" && typeof doc._bsontype === "string" && doc[Symbol.for("@@mdb.bson.version")] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } else if (isBSONType(doc)) { - let outDoc = doc; - if (typeof outDoc.toExtendedJSON !== "function") { - const mapper = BSON_TYPE_MAPPINGS[doc._bsontype]; - if (!mapper) { - throw new BSONError("Unrecognized or invalid _bsontype: " + doc._bsontype); - } - outDoc = mapper(outDoc); - } - if (bsontype === "Code" && outDoc.scope) { - outDoc = new Code(outDoc.code, serializeValue(outDoc.scope, options)); - } else if (bsontype === "DBRef" && outDoc.oid) { - outDoc = new DBRef(serializeValue(outDoc.collection, options), serializeValue(outDoc.oid, options), serializeValue(outDoc.db, options), serializeValue(outDoc.fields, options)); - } - return outDoc.toExtendedJSON(options); - } else { - throw new BSONError("_bsontype must be a string, but was: " + typeof bsontype); - } - } - function parse(text, options) { - const ejsonOptions = { - useBigInt64: options?.useBigInt64 ?? false, - relaxed: options?.relaxed ?? true, - legacy: options?.legacy ?? false - }; - return JSON.parse(text, (key, value) => { - if (key.indexOf("\0") !== -1) { - throw new BSONError(`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(key)}`); - } - return deserializeValue(value, ejsonOptions); - }); - } - function stringify(value, replacer, space, options) { - if (space != null && typeof space === "object") { - options = space; - space = 0; - } - if (replacer != null && typeof replacer === "object" && !Array.isArray(replacer)) { - options = replacer; - replacer = void 0; - space = 0; - } - const serializeOptions = Object.assign({ relaxed: true, legacy: false }, options, { - seenObjects: [{ propertyName: "(root)", obj: null }] - }); - const doc = serializeValue(value, serializeOptions); - return JSON.stringify(doc, replacer, space); - } - function EJSONserialize(value, options) { - options = options || {}; - return JSON.parse(stringify(value, options)); - } - function EJSONdeserialize(ejson, options) { - options = options || {}; - return parse(JSON.stringify(ejson), options); - } - var EJSON = /* @__PURE__ */ Object.create(null); - EJSON.parse = parse; - EJSON.stringify = stringify; - EJSON.serialize = EJSONserialize; - EJSON.deserialize = EJSONdeserialize; - Object.freeze(EJSON); - var MAXSIZE = 1024 * 1024 * 17; - var buffer = ByteUtils.allocate(MAXSIZE); - function setInternalBufferSize(size) { - if (buffer.length < size) { - buffer = ByteUtils.allocate(size); - } - } - function serialize(object, options = {}) { - const checkKeys = typeof options.checkKeys === "boolean" ? options.checkKeys : false; - const serializeFunctions = typeof options.serializeFunctions === "boolean" ? options.serializeFunctions : false; - const ignoreUndefined = typeof options.ignoreUndefined === "boolean" ? options.ignoreUndefined : true; - const minInternalBufferSize = typeof options.minInternalBufferSize === "number" ? options.minInternalBufferSize : MAXSIZE; - if (buffer.length < minInternalBufferSize) { - buffer = ByteUtils.allocate(minInternalBufferSize); - } - const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null); - const finishedBuffer = ByteUtils.allocate(serializationIndex); - finishedBuffer.set(buffer.subarray(0, serializationIndex), 0); - return finishedBuffer; - } - function serializeWithBufferAndIndex(object, finalBuffer, options = {}) { - const checkKeys = typeof options.checkKeys === "boolean" ? options.checkKeys : false; - const serializeFunctions = typeof options.serializeFunctions === "boolean" ? options.serializeFunctions : false; - const ignoreUndefined = typeof options.ignoreUndefined === "boolean" ? options.ignoreUndefined : true; - const startIndex = typeof options.index === "number" ? options.index : 0; - const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null); - finalBuffer.set(buffer.subarray(0, serializationIndex), startIndex); - return startIndex + serializationIndex - 1; - } - function deserialize2(buffer2, options = {}) { - return internalDeserialize(ByteUtils.toLocalBufferType(buffer2), options); - } - function calculateObjectSize(object, options = {}) { - options = options || {}; - const serializeFunctions = typeof options.serializeFunctions === "boolean" ? options.serializeFunctions : false; - const ignoreUndefined = typeof options.ignoreUndefined === "boolean" ? options.ignoreUndefined : true; - return internalCalculateObjectSize(object, serializeFunctions, ignoreUndefined); - } - function deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - const internalOptions = Object.assign({ allowObjectSmallerThanBufferSize: true, index: 0 }, options); - const bufferData = ByteUtils.toLocalBufferType(data); - let index = startIndex; - for (let i = 0; i < numberOfDocuments; i++) { - const size = bufferData[index] | bufferData[index + 1] << 8 | bufferData[index + 2] << 16 | bufferData[index + 3] << 24; - internalOptions.index = index; - documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions); - index = index + size; - } - return index; - } - var bson = /* @__PURE__ */ Object.freeze({ - __proto__: null, - BSONError, - BSONRegExp, - BSONRuntimeError, - BSONSymbol, - BSONType, - BSONValue, - BSONVersionError, - Binary, - Code, - DBRef, - Decimal128, - Double, - EJSON, - Int32, - Long, - MaxKey, - MinKey, - ObjectId, - Timestamp, - UUID, - calculateObjectSize, - deserialize: deserialize2, - deserializeStream, - serialize, - serializeWithBufferAndIndex, - setInternalBufferSize - }); - exports.BSON = bson; - exports.BSONError = BSONError; - exports.BSONRegExp = BSONRegExp; - exports.BSONRuntimeError = BSONRuntimeError; - exports.BSONSymbol = BSONSymbol; - exports.BSONType = BSONType; - exports.BSONValue = BSONValue; - exports.BSONVersionError = BSONVersionError; - exports.Binary = Binary; - exports.Code = Code; - exports.DBRef = DBRef; - exports.Decimal128 = Decimal128; - exports.Double = Double; - exports.EJSON = EJSON; - exports.Int32 = Int32; - exports.Long = Long; - exports.MaxKey = MaxKey; - exports.MinKey = MinKey; - exports.ObjectId = ObjectId; - exports.Timestamp = Timestamp; - exports.UUID = UUID; - exports.calculateObjectSize = calculateObjectSize; - exports.deserialize = deserialize2; - exports.deserializeStream = deserializeStream; - exports.serialize = serialize; - exports.serializeWithBufferAndIndex = serializeWithBufferAndIndex; - exports.setInternalBufferSize = setInternalBufferSize; - } - }); - - // src/jsRunner/bundles/bsonPackage.ts - var bsonPackage_exports = {}; - __export(bsonPackage_exports, { - deserialize: () => deserialize, - toJson: () => toJson - }); - var deserialize = require_bson().deserialize; - var toJson = require_bson().EJSON.deserialize; - return __toCommonJS(bsonPackage_exports); -})(); +"use strict";var bson=(()=>{var Ut=Object.defineProperty;var ve=Object.getOwnPropertyDescriptor;var tn=Object.getOwnPropertyNames;var en=Object.prototype.hasOwnProperty;var nn=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,s)=>(typeof require<"u"?require:t)[s]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var sn=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),rn=(e,t)=>{for(var s in t)Ut(e,s,{get:t[s],enumerable:!0})},on=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of tn(t))!en.call(e,r)&&r!==s&&Ut(e,r,{get:()=>t[r],enumerable:!(n=ve(t,r))||n.enumerable});return e};var fn=e=>on(Ut({},"__esModule",{value:!0}),e);var oe=sn(U=>{"use strict";function vt(e){return["[object ArrayBuffer]","[object SharedArrayBuffer]"].includes(Object.prototype.toString.call(e))}function tt(e){return Object.prototype.toString.call(e)==="[object Uint8Array]"}function lt(e){return Object.prototype.toString.call(e)==="[object RegExp]"}function te(e){return Object.prototype.toString.call(e)==="[object Map]"}function ct(e){return Object.prototype.toString.call(e)==="[object Date]"}function F(e,t){return JSON.stringify(e,(s,n)=>typeof n=="bigint"?{$numberLong:`${n}`}:te(n)?Object.fromEntries(n):n)}function ln(e){if(e!=null&&typeof e=="object"&&"stylize"in e&&typeof e.stylize=="function")return e.stylize}var et=6,At=2147483647,$t=-2147483648,Oe=Math.pow(2,63)-1,be=-Math.pow(2,63),Ee=Math.pow(2,53),Te=-Math.pow(2,53),bt=1,Ie=2,ee=3,de=4,ne=5,cn=6,Ae=7,$e=8,_e=9,se=10,Et=11,hn=12,re=13,Ue=14,Le=15,at=16,Re=17,ie=18,De=19,je=255,ze=127,an=0,Tt=4,Fe=Object.freeze({double:1,string:2,object:3,array:4,binData:5,undefined:6,objectId:7,bool:8,date:9,null:10,regex:11,dbPointer:12,javascript:13,symbol:14,javascriptWithScope:15,int:16,timestamp:17,long:18,decimal:19,minKey:-1,maxKey:127}),a=class extends Error{get bsonError(){return!0}get name(){return"BSONError"}constructor(t,s){super(t,s)}static isBSONError(t){return t!=null&&typeof t=="object"&&"bsonError"in t&&t.bsonError===!0&&"name"in t&&"message"in t&&"stack"in t}},P=class extends a{get name(){return"BSONVersionError"}constructor(){super(`Unsupported BSON version, bson types must be from bson ${et}.x.x`)}},yt=class extends a{get name(){return"BSONRuntimeError"}constructor(t){super(t)}},gn=128,un=192,yn=224,mn=240,wn=248,pn=192,Sn=224,Nn=240,Bn=128;function Me(e,t,s){let n=0;for(let r=t;r20)return null;if(n===1&&e[t]<128)return String.fromCharCode(e[t]);if(n===2&&e[t]<128&&e[t+1]<128)return String.fromCharCode(e[t])+String.fromCharCode(e[t+1]);if(n===3&&e[t]<128&&e[t+1]<128&&e[t+2]<128)return String.fromCharCode(e[t])+String.fromCharCode(e[t+1])+String.fromCharCode(e[t+2]);let r=[];for(let o=t;o127)return null;r.push(c)}return String.fromCharCode(...r)}function On(e){return Z.fromNumberArray(Array.from({length:e},()=>Math.floor(Math.random()*256)))}var bn=(()=>{try{return nn("crypto").randomBytes}catch{return On}})(),Z={toLocalBufferType(e){if(Buffer.isBuffer(e))return e;if(ArrayBuffer.isView(e))return Buffer.from(e.buffer,e.byteOffset,e.byteLength);let t=e?.[Symbol.toStringTag]??Object.prototype.toString.call(e);if(t==="ArrayBuffer"||t==="SharedArrayBuffer"||t==="[object ArrayBuffer]"||t==="[object SharedArrayBuffer]")return Buffer.from(e);throw new a(`Cannot create Buffer from ${String(e)}`)},allocate(e){return Buffer.alloc(e)},equals(e,t){return Z.toLocalBufferType(e).equals(t)},fromNumberArray(e){return Buffer.from(e)},fromBase64(e){return Buffer.from(e,"base64")},toBase64(e){return Z.toLocalBufferType(e).toString("base64")},fromISO88591(e){return Buffer.from(e,"binary")},toISO88591(e){return Z.toLocalBufferType(e).toString("binary")},fromHex(e){return Buffer.from(e,"hex")},toHex(e){return Z.toLocalBufferType(e).toString("hex")},fromUTF8(e){return Buffer.from(e,"utf8")},toUTF8(e,t,s,n){let r=s-t<=20?xe(e,t,s):null;if(r!=null)return r;let o=Z.toLocalBufferType(e).toString("utf8",t,s);if(n){for(let c=0;cMath.floor(Math.random()*256)))}var In=(()=>{let{crypto:e}=globalThis;if(e!=null&&typeof e.getRandomValues=="function")return t=>e.getRandomValues(gt.allocate(t));if(En()){let{console:t}=globalThis;t?.warn?.("BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.")}return Tn})(),fe=/(\d|[a-f])/i,gt={toLocalBufferType(e){let t=e?.[Symbol.toStringTag]??Object.prototype.toString.call(e);if(t==="Uint8Array")return e;if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength));if(t==="ArrayBuffer"||t==="SharedArrayBuffer"||t==="[object ArrayBuffer]"||t==="[object SharedArrayBuffer]")return new Uint8Array(e);throw new a(`Cannot make a Uint8Array from ${String(e)}`)},allocate(e){if(typeof e!="number")throw new TypeError(`The "size" argument must be of type number. Received ${String(e)}`);return new Uint8Array(e)},equals(e,t){if(e.byteLength!==t.byteLength)return!1;for(let s=0;st.charCodeAt(0))},toBase64(e){return btoa(gt.toISO88591(e))},fromISO88591(e){return Uint8Array.from(e,t=>t.charCodeAt(0)&255)},toISO88591(e){return Array.from(Uint16Array.from(e),t=>String.fromCharCode(t)).join("")},fromHex(e){let t=e.length%2===0?e:e.slice(0,e.length-1),s=[];for(let n=0;nt.toString(16).padStart(2,"0")).join("")},fromUTF8(e){return new TextEncoder().encode(e)},toUTF8(e,t,s,n){let r=s-t<=20?xe(e,t,s):null;if(r!=null)return r;if(n)try{return new TextDecoder("utf8",{fatal:n}).decode(e.slice(t,s))}catch(o){throw new a("Invalid UTF-8 string in BSON document",{cause:o})}return new TextDecoder("utf8",{fatal:n}).decode(e.slice(t,s))},utf8ByteLength(e){return gt.fromUTF8(e).byteLength},encodeUTF8Into(e,t,s){let n=gt.fromUTF8(t);return e.set(n,s),n.byteLength},randomBytes:In},dn=typeof Buffer=="function"&&Buffer.prototype?._isBuffer!==!0,l=dn?Z:gt,ut=class extends DataView{static fromUint8Array(t){return new DataView(t.buffer,t.byteOffset,t.byteLength)}},j=class{get[Symbol.for("@@mdb.bson.version")](){return et}[Symbol.for("nodejs.util.inspect.custom")](t,s,n){return this.inspect(t,s,n)}},_=class e extends j{get _bsontype(){return"Binary"}constructor(t,s){if(super(),t!=null&&typeof t=="string"&&!ArrayBuffer.isView(t)&&!vt(t)&&!Array.isArray(t))throw new a("Binary can only be constructed from Uint8Array or number[]");this.sub_type=s??e.BSON_BINARY_SUBTYPE_DEFAULT,t==null?(this.buffer=l.allocate(e.BUFFER_SIZE),this.position=0):(this.buffer=Array.isArray(t)?l.fromNumberArray(t):l.toLocalBufferType(t),this.position=this.buffer.byteLength)}put(t){if(typeof t=="string"&&t.length!==1)throw new a("only accepts single character String");if(typeof t!="number"&&t.length!==1)throw new a("only accepts single character Uint8Array or Array");let s;if(typeof t=="string"?s=t.charCodeAt(0):typeof t=="number"?s=t:s=t[0],s<0||s>255)throw new a("only accepts number in a valid unsigned byte range 0-255");if(this.buffer.byteLength>this.position)this.buffer[this.position++]=s;else{let n=l.allocate(e.BUFFER_SIZE+this.buffer.length);n.set(this.buffer,0),this.buffer=n,this.buffer[this.position++]=s}}write(t,s){if(s=typeof s=="number"?s:this.position,this.buffer.byteLengththis.position?s+t.length:this.position;else if(typeof t=="string")throw new a("input cannot be string")}read(t,s){return s=s&&s>0?s:this.position,this.buffer.slice(t,t+s)}value(){return this.buffer.length===this.position?this.buffer:this.buffer.subarray(0,this.position)}length(){return this.position}toJSON(){return l.toBase64(this.buffer)}toString(t){return t==="hex"?l.toHex(this.buffer):t==="base64"?l.toBase64(this.buffer):t==="utf8"||t==="utf-8"?l.toUTF8(this.buffer,0,this.buffer.byteLength,!1):l.toUTF8(this.buffer,0,this.buffer.byteLength,!1)}toExtendedJSON(t){t=t||{};let s=l.toBase64(this.buffer),n=Number(this.sub_type).toString(16);return t.legacy?{$binary:s,$type:n.length===1?"0"+n:n}:{$binary:{base64:s,subType:n.length===1?"0"+n:n}}}toUUID(){if(this.sub_type===e.SUBTYPE_UUID)return new W(this.buffer.slice(0,this.position));throw new a(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${e.SUBTYPE_UUID}" is currently supported.`)}static createFromHexString(t,s){return new e(l.fromHex(t),s)}static createFromBase64(t,s){return new e(l.fromBase64(t),s)}static fromExtendedJSON(t,s){s=s||{};let n,r;if("$binary"in t?s.legacy&&typeof t.$binary=="string"&&"$type"in t?(r=t.$type?parseInt(t.$type,16):0,n=l.fromBase64(t.$binary)):typeof t.$binary!="string"&&(r=t.$binary.subType?parseInt(t.$binary.subType,16):0,n=l.fromBase64(t.$binary.base64)):"$uuid"in t&&(r=4,n=W.bytesFromString(t.$uuid)),!n)throw new a(`Unexpected Binary Extended JSON format ${JSON.stringify(t)}`);return r===Tt?new W(n):new e(n,r)}inspect(t,s,n){n??=F;let r=l.toBase64(this.buffer.subarray(0,this.position)),o=n(r,s),c=n(this.sub_type,s);return`Binary.createFromBase64(${o}, ${c})`}};_.BSON_BINARY_SUBTYPE_DEFAULT=0;_.BUFFER_SIZE=256;_.SUBTYPE_DEFAULT=0;_.SUBTYPE_FUNCTION=1;_.SUBTYPE_BYTE_ARRAY=2;_.SUBTYPE_UUID_OLD=3;_.SUBTYPE_UUID=4;_.SUBTYPE_MD5=5;_.SUBTYPE_ENCRYPTED=6;_.SUBTYPE_COLUMN=7;_.SUBTYPE_USER_DEFINED=128;var Lt=16,An=/^[0-9A-F]{32}$/i,$n=/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i,W=class e extends _{constructor(t){let s;if(t==null)s=e.generate();else if(t instanceof e)s=l.toLocalBufferType(new Uint8Array(t.buffer));else if(ArrayBuffer.isView(t)&&t.byteLength===Lt)s=l.toLocalBufferType(t);else if(typeof t=="string")s=e.bytesFromString(t);else throw new a("Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).");super(s,Tt)}get id(){return this.buffer}set id(t){this.buffer=t}toHexString(t=!0){return t?[l.toHex(this.buffer.subarray(0,4)),l.toHex(this.buffer.subarray(4,6)),l.toHex(this.buffer.subarray(6,8)),l.toHex(this.buffer.subarray(8,10)),l.toHex(this.buffer.subarray(10,16))].join("-"):l.toHex(this.buffer)}toString(t){return t==="hex"?l.toHex(this.id):t==="base64"?l.toBase64(this.id):this.toHexString()}toJSON(){return this.toHexString()}equals(t){if(!t)return!1;if(t instanceof e)return l.equals(t.id,this.id);try{return l.equals(new e(t).id,this.id)}catch{return!1}}toBinary(){return new _(this.id,_.SUBTYPE_UUID)}static generate(){let t=l.randomBytes(Lt);return t[6]=t[6]&15|64,t[8]=t[8]&63|128,t}static isValid(t){return t?typeof t=="string"?e.isValidUUIDString(t):tt(t)?t.byteLength===Lt:t._bsontype==="Binary"&&t.sub_type===this.SUBTYPE_UUID&&t.buffer.byteLength===16:!1}static createFromHexString(t){let s=e.bytesFromString(t);return new e(s)}static createFromBase64(t){return new e(l.fromBase64(t))}static bytesFromString(t){if(!e.isValidUUIDString(t))throw new a("UUID string representation must be 32 hex digits or canonical hyphenated representation");return l.fromHex(t.replace(/-/g,""))}static isValidUUIDString(t){return An.test(t)||$n.test(t)}inspect(t,s,n){return n??=F,`new UUID(${n(this.toHexString(),s)})`}},Y=class e extends j{get _bsontype(){return"Code"}constructor(t,s){super(),this.code=t.toString(),this.scope=s??null}toJSON(){return this.scope!=null?{code:this.code,scope:this.scope}:{code:this.code}}toExtendedJSON(){return this.scope?{$code:this.code,$scope:this.scope}:{$code:this.code}}static fromExtendedJSON(t){return new e(t.$code,t.$scope)}inspect(t,s,n){n??=F;let r=n(this.code,s),o=r.includes(` +`);this.scope!=null&&(r+=`,${o?` +`:" "}${n(this.scope,s)}`);let c=o&&this.scope===null;return`new Code(${o?` +`:""}${r}${c?` +`:""})`}};function Je(e){return e!=null&&typeof e=="object"&&"$id"in e&&e.$id!=null&&"$ref"in e&&typeof e.$ref=="string"&&(!("$db"in e)||"$db"in e&&typeof e.$db=="string")}var C=class e extends j{get _bsontype(){return"DBRef"}constructor(t,s,n,r){super();let o=t.split(".");o.length===2&&(n=o.shift(),t=o.shift()),this.collection=t,this.oid=s,this.db=n,this.fields=r||{}}get namespace(){return this.collection}set namespace(t){this.collection=t}toJSON(){let t=Object.assign({$ref:this.collection,$id:this.oid},this.fields);return this.db!=null&&(t.$db=this.db),t}toExtendedJSON(t){t=t||{};let s={$ref:this.collection,$id:this.oid};return t.legacy||(this.db&&(s.$db=this.db),s=Object.assign(s,this.fields)),s}static fromExtendedJSON(t){let s=Object.assign({},t);return delete s.$ref,delete s.$id,delete s.$db,new e(t.$ref,t.$id,t.$db,s)}inspect(t,s,n){n??=F;let r=[n(this.namespace,s),n(this.oid,s),...this.db?[n(this.db,s)]:[],...Object.keys(this.fields).length>0?[n(this.fields,s)]:[]];return r[1]=n===F?`new ObjectId(${r[1]})`:r[1],`new DBRef(${r.join(", ")})`}},M;try{M=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,0,11,7,50,6,3,109,117,108,0,1,5,100,105,118,95,115,0,2,5,100,105,118,95,117,0,3,5,114,101,109,95,115,0,4,5,114,101,109,95,117,0,5,8,103,101,116,95,104,105,103,104,0,0,10,191,1,6,4,0,35,0,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,126,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,127,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,128,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,129,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,130,34,4,66,32,135,167,36,0,32,4,167,11])),{}).exports}catch{}var le=65536,_n=1<<24,ht=le*le,Ce=ht*ht,ce=Ce/2,he={},ae={},Un=20,Ln=/^(\+?0|(\+|-)?[1-9][0-9]*)$/,y=class e extends j{get _bsontype(){return"Long"}get __isLong__(){return!0}constructor(t=0,s,n){super(),typeof t=="bigint"?Object.assign(this,e.fromBigInt(t,!!s)):typeof t=="string"?Object.assign(this,e.fromString(t,!!s)):(this.low=t|0,this.high=s|0,this.unsigned=!!n)}static fromBits(t,s,n){return new e(t,s,n)}static fromInt(t,s){let n,r,o;return s?(t>>>=0,(o=0<=t&&t<256)&&(r=ae[t],r)?r:(n=e.fromBits(t,(t|0)<0?-1:0,!0),o&&(ae[t]=n),n)):(t|=0,(o=-128<=t&&t<128)&&(r=he[t],r)?r:(n=e.fromBits(t,t<0?-1:0,!1),o&&(he[t]=n),n))}static fromNumber(t,s){if(isNaN(t))return s?e.UZERO:e.ZERO;if(s){if(t<0)return e.UZERO;if(t>=Ce)return e.MAX_UNSIGNED_VALUE}else{if(t<=-ce)return e.MIN_VALUE;if(t+1>=ce)return e.MAX_VALUE}return t<0?e.fromNumber(-t,s).neg():e.fromBits(t%ht|0,t/ht|0,s)}static fromBigInt(t,s){return e.fromString(t.toString(),s)}static fromString(t,s,n){if(t.length===0)throw new a("empty string");if(t==="NaN"||t==="Infinity"||t==="+Infinity"||t==="-Infinity")return e.ZERO;if(typeof s=="number"?(n=s,s=!1):s=!!s,n=n||10,n<2||360)throw new a("interior hyphen");if(r===0)return e.fromString(t.substring(1),s,n).neg();let o=e.fromNumber(Math.pow(n,8)),c=e.ZERO;for(let g=0;g>>16,n=this.high&65535,r=this.low>>>16,o=this.low&65535,c=t.high>>>16,g=t.high&65535,i=t.low>>>16,S=t.low&65535,u=0,f=0,h=0,N=0;return N+=o+S,h+=N>>>16,N&=65535,h+=r+i,f+=h>>>16,h&=65535,f+=n+g,u+=f>>>16,f&=65535,u+=s+c,u&=65535,e.fromBits(h<<16|N,u<<16|f,this.unsigned)}and(t){return e.isLong(t)||(t=e.fromValue(t)),e.fromBits(this.low&t.low,this.high&t.high,this.unsigned)}compare(t){if(e.isLong(t)||(t=e.fromValue(t)),this.eq(t))return 0;let s=this.isNegative(),n=t.isNegative();return s&&!n?-1:!s&&n?1:this.unsigned?t.high>>>0>this.high>>>0||t.high===this.high&&t.low>>>0>this.low>>>0?-1:1:this.sub(t).isNegative()?-1:1}comp(t){return this.compare(t)}divide(t){if(e.isLong(t)||(t=e.fromValue(t)),t.isZero())throw new a("division by zero");if(M){if(!this.unsigned&&this.high===-2147483648&&t.low===-1&&t.high===-1)return this;let o=(this.unsigned?M.div_u:M.div_s)(this.low,this.high,t.low,t.high);return e.fromBits(o,M.get_high(),this.unsigned)}if(this.isZero())return this.unsigned?e.UZERO:e.ZERO;let s,n,r;if(this.unsigned){if(t.unsigned||(t=t.toUnsigned()),t.gt(this))return e.UZERO;if(t.gt(this.shru(1)))return e.UONE;r=e.UZERO}else{if(this.eq(e.MIN_VALUE))return t.eq(e.ONE)||t.eq(e.NEG_ONE)?e.MIN_VALUE:t.eq(e.MIN_VALUE)?e.ONE:(s=this.shr(1).div(t).shl(1),s.eq(e.ZERO)?t.isNegative()?e.ONE:e.NEG_ONE:(n=this.sub(t.mul(s)),r=s.add(n.div(t)),r));if(t.eq(e.MIN_VALUE))return this.unsigned?e.UZERO:e.ZERO;if(this.isNegative())return t.isNegative()?this.neg().div(t.neg()):this.neg().div(t).neg();if(t.isNegative())return this.div(t.neg()).neg();r=e.ZERO}for(n=this;n.gte(t);){s=Math.max(1,Math.floor(n.toNumber()/t.toNumber()));let o=Math.ceil(Math.log(s)/Math.LN2),c=o<=48?1:Math.pow(2,o-48),g=e.fromNumber(s),i=g.mul(t);for(;i.isNegative()||i.gt(n);)s-=c,g=e.fromNumber(s,this.unsigned),i=g.mul(t);g.isZero()&&(g=e.ONE),r=r.add(g),n=n.sub(i)}return r}div(t){return this.divide(t)}equals(t){return e.isLong(t)||(t=e.fromValue(t)),this.unsigned!==t.unsigned&&this.high>>>31===1&&t.high>>>31===1?!1:this.high===t.high&&this.low===t.low}eq(t){return this.equals(t)}getHighBits(){return this.high}getHighBitsUnsigned(){return this.high>>>0}getLowBits(){return this.low}getLowBitsUnsigned(){return this.low>>>0}getNumBitsAbs(){if(this.isNegative())return this.eq(e.MIN_VALUE)?64:this.neg().getNumBitsAbs();let t=this.high!==0?this.high:this.low,s;for(s=31;s>0&&!(t&1<0}gt(t){return this.greaterThan(t)}greaterThanOrEqual(t){return this.comp(t)>=0}gte(t){return this.greaterThanOrEqual(t)}ge(t){return this.greaterThanOrEqual(t)}isEven(){return(this.low&1)===0}isNegative(){return!this.unsigned&&this.high<0}isOdd(){return(this.low&1)===1}isPositive(){return this.unsigned||this.high>=0}isZero(){return this.high===0&&this.low===0}lessThan(t){return this.comp(t)<0}lt(t){return this.lessThan(t)}lessThanOrEqual(t){return this.comp(t)<=0}lte(t){return this.lessThanOrEqual(t)}modulo(t){if(e.isLong(t)||(t=e.fromValue(t)),M){let s=(this.unsigned?M.rem_u:M.rem_s)(this.low,this.high,t.low,t.high);return e.fromBits(s,M.get_high(),this.unsigned)}return this.sub(this.div(t).mul(t))}mod(t){return this.modulo(t)}rem(t){return this.modulo(t)}multiply(t){if(this.isZero())return e.ZERO;if(e.isLong(t)||(t=e.fromValue(t)),M){let p=M.mul(this.low,this.high,t.low,t.high);return e.fromBits(p,M.get_high(),this.unsigned)}if(t.isZero())return e.ZERO;if(this.eq(e.MIN_VALUE))return t.isOdd()?e.MIN_VALUE:e.ZERO;if(t.eq(e.MIN_VALUE))return this.isOdd()?e.MIN_VALUE:e.ZERO;if(this.isNegative())return t.isNegative()?this.neg().mul(t.neg()):this.neg().mul(t).neg();if(t.isNegative())return this.mul(t.neg()).neg();if(this.lt(e.TWO_PWR_24)&&t.lt(e.TWO_PWR_24))return e.fromNumber(this.toNumber()*t.toNumber(),this.unsigned);let s=this.high>>>16,n=this.high&65535,r=this.low>>>16,o=this.low&65535,c=t.high>>>16,g=t.high&65535,i=t.low>>>16,S=t.low&65535,u=0,f=0,h=0,N=0;return N+=o*S,h+=N>>>16,N&=65535,h+=r*S,f+=h>>>16,h&=65535,h+=o*i,f+=h>>>16,h&=65535,f+=n*S,u+=f>>>16,f&=65535,f+=r*i,u+=f>>>16,f&=65535,f+=o*g,u+=f>>>16,f&=65535,u+=s*S+n*i+r*g+o*c,u&=65535,e.fromBits(h<<16|N,u<<16|f,this.unsigned)}mul(t){return this.multiply(t)}negate(){return!this.unsigned&&this.eq(e.MIN_VALUE)?e.MIN_VALUE:this.not().add(e.ONE)}neg(){return this.negate()}not(){return e.fromBits(~this.low,~this.high,this.unsigned)}notEquals(t){return!this.equals(t)}neq(t){return this.notEquals(t)}ne(t){return this.notEquals(t)}or(t){return e.isLong(t)||(t=e.fromValue(t)),e.fromBits(this.low|t.low,this.high|t.high,this.unsigned)}shiftLeft(t){return e.isLong(t)&&(t=t.toInt()),(t&=63)===0?this:t<32?e.fromBits(this.low<>>32-t,this.unsigned):e.fromBits(0,this.low<>>t|this.high<<32-t,this.high>>t,this.unsigned):e.fromBits(this.high>>t-32,this.high>=0?0:-1,this.unsigned)}shr(t){return this.shiftRight(t)}shiftRightUnsigned(t){if(e.isLong(t)&&(t=t.toInt()),t&=63,t===0)return this;{let s=this.high;if(t<32){let n=this.low;return e.fromBits(n>>>t|s<<32-t,s>>>t,this.unsigned)}else return t===32?e.fromBits(s,0,this.unsigned):e.fromBits(s>>>t-32,0,this.unsigned)}}shr_u(t){return this.shiftRightUnsigned(t)}shru(t){return this.shiftRightUnsigned(t)}subtract(t){return e.isLong(t)||(t=e.fromValue(t)),this.add(t.neg())}sub(t){return this.subtract(t)}toInt(){return this.unsigned?this.low>>>0:this.low}toNumber(){return this.unsigned?(this.high>>>0)*ht+(this.low>>>0):this.high*ht+(this.low>>>0)}toBigInt(){return BigInt(this.toString())}toBytes(t){return t?this.toBytesLE():this.toBytesBE()}toBytesLE(){let t=this.high,s=this.low;return[s&255,s>>>8&255,s>>>16&255,s>>>24,t&255,t>>>8&255,t>>>16&255,t>>>24]}toBytesBE(){let t=this.high,s=this.low;return[t>>>24,t>>>16&255,t>>>8&255,t&255,s>>>24,s>>>16&255,s>>>8&255,s&255]}toSigned(){return this.unsigned?e.fromBits(this.low,this.high,!1):this}toString(t){if(t=t||10,t<2||36>>0).toString(t);if(n=o,n.isZero())return g+r;for(;g.length<6;)g="0"+g;r=""+g+r}}toUnsigned(){return this.unsigned?this:e.fromBits(this.low,this.high,!0)}xor(t){return e.isLong(t)||(t=e.fromValue(t)),e.fromBits(this.low^t.low,this.high^t.high,this.unsigned)}eqz(){return this.isZero()}le(t){return this.lessThanOrEqual(t)}toExtendedJSON(t){return t&&t.relaxed?this.toNumber():{$numberLong:this.toString()}}static fromExtendedJSON(t,s){let{useBigInt64:n=!1,relaxed:r=!0}={...s};if(t.$numberLong.length>Un)throw new a("$numberLong string is too long");if(!Ln.test(t.$numberLong))throw new a(`$numberLong string "${t.$numberLong}" is in an invalid format`);if(n){let c=BigInt(t.$numberLong);return BigInt.asIntN(64,c)}let o=e.fromString(t.$numberLong);return r?o.toNumber():o}inspect(t,s,n){n??=F;let r=n(this.toString(),s),o=this.unsigned?`, ${n(this.unsigned,s)}`:"";return`new Long(${r}${o})`}};y.TWO_PWR_24=y.fromInt(_n);y.MAX_UNSIGNED_VALUE=y.fromBits(-1,-1,!0);y.ZERO=y.fromInt(0);y.UZERO=y.fromInt(0,!0);y.ONE=y.fromInt(1);y.UONE=y.fromInt(1,!0);y.NEG_ONE=y.fromInt(-1);y.MAX_VALUE=y.fromBits(-1,2147483647,!1);y.MIN_VALUE=y.fromBits(0,-2147483648,!1);var Rn=/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/,Dn=/^(\+|-)?(Infinity|inf)$/i,jn=/^(\+|-)?NaN$/i,ft=6111,wt=-6176,ge=6176,ue=34,Rt=l.fromNumberArray([124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse()),ye=l.fromNumberArray([248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse()),me=l.fromNumberArray([120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse()),zn=/^([-+])?(\d+)?$/,Fn=31,we=16383,Mn=30,xn=31;function pe(e){return!isNaN(parseInt(e,10))}function Jn(e){let t=y.fromNumber(1e9),s=y.fromNumber(0);if(!e.parts[0]&&!e.parts[1]&&!e.parts[2]&&!e.parts[3])return{quotient:e,rem:s};for(let n=0;n<=3;n++)s=s.shiftLeft(32),s=s.add(new y(e.parts[n],0)),e.parts[n]=s.div(t).low,s=s.modulo(t);return{quotient:e,rem:s}}function Cn(e,t){if(!e&&!t)return{high:y.fromNumber(0),low:y.fromNumber(0)};let s=e.shiftRightUnsigned(32),n=new y(e.getLowBits(),0),r=t.shiftRightUnsigned(32),o=new y(t.getLowBits(),0),c=s.multiply(r),g=s.multiply(o),i=n.multiply(r),S=n.multiply(o);return c=c.add(g.shiftRightUnsigned(32)),g=new y(g.getLowBits(),0).add(i).add(S.shiftRightUnsigned(32)),c=c.add(g.shiftRightUnsigned(32)),S=g.shiftLeft(32).add(new y(S.getLowBits(),0)),{high:c,low:S}}function Hn(e,t){let s=e.high>>>0,n=t.high>>>0;if(s>>0,o=t.low>>>0;if(r=7e3)throw new a(""+t+" not a valid Decimal128 string");let R=t.match(Rn),Nt=t.match(Dn),T=t.match(jn);if(!R&&!Nt&&!T||t.length===0)throw new a(""+t+" not a valid Decimal128 string");if(R){let w=R[2],m=R[4],b=R[5],I=R[6];m&&I===void 0&&J(t,"missing exponent power"),m&&w===void 0&&J(t,"missing exponent base"),m===void 0&&(b||I)&&J(t,"missing e before exponent")}if((t[B]==="+"||t[B]==="-")&&(r=!0,n=t[B++]==="-"),!pe(t[B])&&t[B]!=="."){if(t[B]==="i"||t[B]==="I")return new e(n?ye:me);if(t[B]==="N")return new e(Rt)}for(;pe(t[B])||t[B]===".";){if(t[B]==="."){o&&J(t,"contains multiple periods"),o=!0,B=B+1;continue}N$+16384?$=wt:$=$-u;$>ft;){if(E=E+1,E>=ue){if(g===0){$=ft;break}J(t,"overflow")}$=$-1}if(s.allowRounding){for(;$=5&&(b=1,m===5)){b=h[E]%2===1?1:0;for(let I=f+E+2;I=0&&++h[I]>9;I--)if(h[I]=0,I===0)if($>8&255,L[B++]=d.low.low>>16&255,L[B++]=d.low.low>>24&255,L[B++]=d.low.high&255,L[B++]=d.low.high>>8&255,L[B++]=d.low.high>>16&255,L[B++]=d.low.high>>24&255,L[B++]=d.high.low&255,L[B++]=d.high.low>>8&255,L[B++]=d.high.low>>16&255,L[B++]=d.high.low>>24&255,L[B++]=d.high.high&255,L[B++]=d.high.high>>8&255,L[B++]=d.high.high>>16&255,L[B++]=d.high.high>>24&255,new e(L)}toString(){let t,s=0,n=new Array(36);for(let B=0;B>26&Fn;if(D>>3===3){if(D===Mn)return u.join("")+"Infinity";if(D===xn)return"NaN";t=E>>15&we,c=8+(E>>14&1)}else c=E>>14&7,t=E>>17&we;let A=t-ge;if(g.parts[0]=(E&16383)+((c&15)<<14),g.parts[1]=p,g.parts[2]=N,g.parts[3]=h,g.parts[0]===0&&g.parts[1]===0&&g.parts[2]===0&&g.parts[3]===0)o=!0;else for(S=3;S>=0;S--){let B=0,R=Jn(g);if(g=R.quotient,B=R.rem.low,!!B)for(i=8;i>=0;i--)n[S*9+i]=B%10,B=Math.floor(B/10)}if(o)s=1,n[r]=0;else for(s=36;!n[r];)s=s-1,r=r+1;let x=s-1+A;if(x>=34||x<=-7||A>0){if(s>34)return u.push("0"),A>0?u.push(`E+${A}`):A<0&&u.push(`E${A}`),u.join("");u.push(`${n[r++]}`),s=s-1,s&&u.push(".");for(let B=0;B0?u.push(`+${x}`):u.push(`${x}`)}else if(A>=0)for(let B=0;B0)for(let R=0;R>8&255,n[9]=s>>16&255,n}toString(t){return t==="base64"?l.toBase64(this.id):t==="hex"?this.toHexString():this.toHexString()}toJSON(){return this.toHexString()}static is(t){return t!=null&&typeof t=="object"&&"_bsontype"in t&&t._bsontype==="ObjectId"}equals(t){if(t==null)return!1;if(e.is(t))return this[H][11]===t[H][11]&&l.equals(this[H],t[H]);if(typeof t=="string")return t.toLowerCase()===this.toHexString();if(typeof t=="object"&&typeof t.toHexString=="function"){let s=t.toHexString(),n=this.toHexString();return typeof s=="string"&&s.toLowerCase()===n}return!1}getTimestamp(){let t=new Date,s=ut.fromUint8Array(this.id).getUint32(0,!1);return t.setTime(Math.floor(s)*1e3),t}static createPk(){return new e}static createFromTime(t){let s=l.fromNumberArray([0,0,0,0,0,0,0,0,0,0,0,0]);return ut.fromUint8Array(s).setUint32(0,t,!1),new e(s)}static createFromHexString(t){if(t?.length!==24)throw new a("hex string must be 24 characters");return new e(l.fromHex(t))}static createFromBase64(t){if(t?.length!==16)throw new a("base64 string must be 16 characters");return new e(l.fromBase64(t))}static isValid(t){if(t==null)return!1;try{return new e(t),!0}catch{return!1}}toExtendedJSON(){return this.toHexString?{$oid:this.toHexString()}:{$oid:this.toString("hex")}}static fromExtendedJSON(t){return new e(t.$oid)}inspect(t,s,n){return n??=F,`new ObjectId(${n(this.toHexString(),s)})`}};k.index=Math.floor(Math.random()*16777215);function Bt(e,t,s){let n=5;if(Array.isArray(e))for(let r=0;r=Te&&t<=Ee&&t>=$t&&t<=At?(e!=null?l.utf8ByteLength(e)+1:0)+(4+1):(e!=null?l.utf8ByteLength(e)+1:0)+(8+1);case"undefined":return n||!r?(e!=null?l.utf8ByteLength(e)+1:0)+1:0;case"boolean":return(e!=null?l.utf8ByteLength(e)+1:0)+(1+1);case"object":if(t!=null&&typeof t._bsontype=="string"&&t[Symbol.for("@@mdb.bson.version")]!==et)throw new P;if(t==null||t._bsontype==="MinKey"||t._bsontype==="MaxKey")return(e!=null?l.utf8ByteLength(e)+1:0)+1;if(t._bsontype==="ObjectId")return(e!=null?l.utf8ByteLength(e)+1:0)+(12+1);if(t instanceof Date||ct(t))return(e!=null?l.utf8ByteLength(e)+1:0)+(8+1);if(ArrayBuffer.isView(t)||t instanceof ArrayBuffer||vt(t))return(e!=null?l.utf8ByteLength(e)+1:0)+(1+4+1)+t.byteLength;if(t._bsontype==="Long"||t._bsontype==="Double"||t._bsontype==="Timestamp")return(e!=null?l.utf8ByteLength(e)+1:0)+(8+1);if(t._bsontype==="Decimal128")return(e!=null?l.utf8ByteLength(e)+1:0)+(16+1);if(t._bsontype==="Code")return t.scope!=null&&Object.keys(t.scope).length>0?(e!=null?l.utf8ByteLength(e)+1:0)+1+4+4+l.utf8ByteLength(t.code.toString())+1+Bt(t.scope,s,r):(e!=null?l.utf8ByteLength(e)+1:0)+1+4+l.utf8ByteLength(t.code.toString())+1;if(t._bsontype==="Binary"){let o=t;return o.sub_type===_.SUBTYPE_BYTE_ARRAY?(e!=null?l.utf8ByteLength(e)+1:0)+(o.position+1+4+1+4):(e!=null?l.utf8ByteLength(e)+1:0)+(o.position+1+4+1)}else{if(t._bsontype==="Symbol")return(e!=null?l.utf8ByteLength(e)+1:0)+l.utf8ByteLength(t.value)+4+1+1;if(t._bsontype==="DBRef"){let o=Object.assign({$ref:t.collection,$id:t.oid},t.fields);return t.db!=null&&(o.$db=t.db),(e!=null?l.utf8ByteLength(e)+1:0)+1+Bt(o,s,r)}else return t instanceof RegExp||lt(t)?(e!=null?l.utf8ByteLength(e)+1:0)+1+l.utf8ByteLength(t.source)+1+(t.global?1:0)+(t.ignoreCase?1:0)+(t.multiline?1:0)+1:t._bsontype==="BSONRegExp"?(e!=null?l.utf8ByteLength(e)+1:0)+1+l.utf8ByteLength(t.pattern)+1+l.utf8ByteLength(t.options)+1:(e!=null?l.utf8ByteLength(e)+1:0)+Bt(t,s,r)+1}case"function":if(s)return(e!=null?l.utf8ByteLength(e)+1:0)+1+4+l.utf8ByteLength(t.toString())+1}return 0}function Pn(e){return e.split("").sort().join("")}var q=class e extends j{get _bsontype(){return"BSONRegExp"}constructor(t,s){if(super(),this.pattern=t,this.options=Pn(s??""),this.pattern.indexOf("\0")!==-1)throw new a(`BSON Regex patterns cannot contain null bytes, found: ${JSON.stringify(this.pattern)}`);if(this.options.indexOf("\0")!==-1)throw new a(`BSON Regex options cannot contain null bytes, found: ${JSON.stringify(this.options)}`);for(let n=0;ng);n??=F;let o=r(n(this.pattern),"regexp"),c=r(n(this.options),"regexp");return`new BSONRegExp(${o}, ${c})`}},it=class e extends j{get _bsontype(){return"BSONSymbol"}constructor(t){super(),this.value=t}valueOf(){return this.value}toString(){return this.value}toJSON(){return this.value}toExtendedJSON(){return{$symbol:this.value}}static fromExtendedJSON(t){return new e(t.$symbol)}inspect(t,s,n){return n??=F,`new BSONSymbol(${n(this.value,s)})`}},Wn=y,Q=class e extends Wn{get _bsontype(){return"Timestamp"}constructor(t){if(t==null)super(0,0,!0);else if(typeof t=="bigint")super(t,!0);else if(y.isLong(t))super(t.low,t.high,!0);else if(typeof t=="object"&&"t"in t&&"i"in t){if(typeof t.t!="number"&&(typeof t.t!="object"||t.t._bsontype!=="Int32"))throw new a("Timestamp constructed from { t, i } must provide t as a number");if(typeof t.i!="number"&&(typeof t.i!="object"||t.i._bsontype!=="Int32"))throw new a("Timestamp constructed from { t, i } must provide i as a number");let s=Number(t.t),n=Number(t.i);if(s<0||Number.isNaN(s))throw new a("Timestamp constructed from { t, i } must provide a positive t");if(n<0||Number.isNaN(n))throw new a("Timestamp constructed from { t, i } must provide a positive i");if(s>4294967295)throw new a("Timestamp constructed from { t, i } must provide t equal or less than uint32 max");if(n>4294967295)throw new a("Timestamp constructed from { t, i } must provide i equal or less than uint32 max");super(n,s,!0)}else throw new a("A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }")}toJSON(){return{$timestamp:this.toString()}}static fromInt(t){return new e(y.fromInt(t,!0))}static fromNumber(t){return new e(y.fromNumber(t,!0))}static fromBits(t,s){return new e({i:t,t:s})}static fromString(t,s){return new e(y.fromString(t,!0,s))}toExtendedJSON(){return{$timestamp:{t:this.high>>>0,i:this.low>>>0}}}static fromExtendedJSON(t){let s=y.isLong(t.$timestamp.i)?t.$timestamp.i.getLowBitsUnsigned():t.$timestamp.i,n=y.isLong(t.$timestamp.t)?t.$timestamp.t.getLowBitsUnsigned():t.$timestamp.t;return new e({t:n,i:s})}inspect(t,s,n){n??=F;let r=n(this.high>>>0,s),o=n(this.low>>>0,s);return`new Timestamp({ t: ${r}, i: ${o} })`}};Q.MAX_VALUE=y.MAX_UNSIGNED_VALUE;var Yn=y.fromNumber(Ee),kn=y.fromNumber(Te);function He(e,t,s){t=t??{};let n=t&&t.index?t.index:0,r=e[n]|e[n+1]<<8|e[n+2]<<16|e[n+3]<<24;if(r<5)throw new a(`bson size must be >= 5, is ${r}`);if(t.allowObjectSmallerThanBufferSize&&e.length= bson size ${r}`);if(!t.allowObjectSmallerThanBufferSize&&e.length!==r)throw new a(`buffer length ${e.length} must === bson size ${r}`);if(r+n>e.byteLength)throw new a(`(bson size ${r} + options.index ${n} must be <= buffer length ${e.byteLength})`);if(e[n+r-1]!==0)throw new a("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");return Ot(e,n,t,s)}var qn=/^\$ref$|^\$id$|^\$db$/;function Ot(e,t,s,n=!1){let r=s.fieldsAsRaw==null?null:s.fieldsAsRaw,o=s.raw==null?!1:s.raw,c=typeof s.bsonRegExp=="boolean"?s.bsonRegExp:!1,g=s.promoteBuffers??!1,i=s.promoteLongs??!0,S=s.promoteValues??!0,u=s.useBigInt64??!1;if(u&&!S)throw new a("Must either request bigint or Long for int64 deserialization");if(u&&!i)throw new a("Must either request bigint or Long for int64 deserialization");let f=s.validation==null?{utf8:!0}:s.validation,h=!0,N,p=new Set,E=f.utf8;if(typeof E=="boolean")N=E;else{h=!1;let T=Object.keys(E).map(function(O){return E[O]});if(T.length===0)throw new a("UTF-8 validation setting cannot be empty");if(typeof T[0]!="boolean")throw new a("Invalid UTF-8 validation option, must specify boolean values");if(N=T[0],!T.every(O=>O===N))throw new a("Invalid UTF-8 validation option - keys must be all true or all false")}if(!h)for(let T of Object.keys(E))p.add(T);let $=t;if(e.length<5)throw new a("corrupt bson message < 5 bytes long");let D=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(D<5||D>e.length)throw new a("corrupt bson message");let A=n?[]:{},x=0,B=!1,R=n?!1:null,Nt=new DataView(e.buffer,e.byteOffset,e.byteLength);for(;!B;){let T=e[t++];if(T===0)break;let O=t;for(;e[O]!==0&&O=e.byteLength)throw new a("Bad BSON Document: illegal CString");let d=n?x++:l.toUTF8(e,t,O,!1),L=!0;h||p.has(d)?L=N:L=!N,R!==!1&&d[0]==="$"&&(R=qn.test(d));let w;if(t=O+1,T===Ie){let m=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(m<=0||m>e.length-t||e[t+m-1]!==0)throw new a("bad string length in bson");w=l.toUTF8(e,t,t+m-1,L),t=t+m}else if(T===Ae){let m=l.allocate(12);m.set(e.subarray(t,t+12)),w=new k(m),t=t+12}else if(T===at&&S===!1)w=new X(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24);else if(T===at)w=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;else if(T===bt&&S===!1)w=new G(Nt.getFloat64(t,!0)),t=t+8;else if(T===bt)w=Nt.getFloat64(t,!0),t=t+8;else if(T===_e){let m=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,b=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;w=new Date(new y(m,b).toNumber())}else if(T===$e){if(e[t]!==0&&e[t]!==1)throw new a("illegal boolean type value");w=e[t++]===1}else if(T===ee){let m=t,b=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24;if(b<=0||b>e.length-t)throw new a("bad embedded document length in bson");if(o)w=e.slice(t,t+b);else{let I=s;h||(I={...s,validation:{utf8:L}}),w=Ot(e,m,I,!1)}t=t+b}else if(T===de){let m=t,b=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24,I=s,z=t+b;if(r&&r[d]&&(I={...s,raw:!0}),h||(I={...I,validation:{utf8:L}}),w=Ot(e,m,I,!0),t=t+b,e[t-1]!==0)throw new a("invalid array terminator byte");if(t!==z)throw new a("corrupted array bson")}else if(T===cn)w=void 0;else if(T===se)w=null;else if(T===ie){let m=ut.fromUint8Array(e.subarray(t,t+8)),b=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,I=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,z=new y(b,I);u?w=m.getBigInt64(0,!0):i&&S===!0?w=z.lessThanOrEqual(Yn)&&z.greaterThanOrEqual(kn)?z.toNumber():z:w=z}else if(T===De){let m=l.allocate(16);m.set(e.subarray(t,t+16),0),t=t+16,w=new nt(m)}else if(T===ne){let m=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,b=m,I=e[t++];if(m<0)throw new a("Negative binary type element size found");if(m>e.byteLength)throw new a("Binary type size larger than document size");if(e.slice!=null){if(I===_.SUBTYPE_BYTE_ARRAY){if(m=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,m<0)throw new a("Negative binary type element size found for subtype 0x02");if(m>b-4)throw new a("Binary type with subtype 0x02 contains too long binary size");if(mb-4)throw new a("Binary type with subtype 0x02 contains too long binary size");if(m=e.length)throw new a("Bad BSON Document: illegal CString");let m=l.toUTF8(e,t,O,!1);for(t=O+1,O=t;e[O]!==0&&O=e.length)throw new a("Bad BSON Document: illegal CString");let b=l.toUTF8(e,t,O,!1);t=O+1;let I=new Array(b.length);for(O=0;O=e.length)throw new a("Bad BSON Document: illegal CString");let m=l.toUTF8(e,t,O,!1);for(t=O+1,O=t;e[O]!==0&&O=e.length)throw new a("Bad BSON Document: illegal CString");let b=l.toUTF8(e,t,O,!1);t=O+1,w=new q(m,b)}else if(T===Ue){let m=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(m<=0||m>e.length-t||e[t+m-1]!==0)throw new a("bad string length in bson");let b=l.toUTF8(e,t,t+m-1,L);w=S?b:new it(b),t=t+m}else if(T===Re){let m=e[t++]+e[t++]*256+e[t++]*65536+e[t++]*16777216,b=e[t++]+e[t++]*256+e[t++]*65536+e[t++]*(1<<24);w=new Q({i:m,t:b})}else if(T===je)w=new rt;else if(T===ze)w=new st;else if(T===re){let m=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(m<=0||m>e.length-t||e[t+m-1]!==0)throw new a("bad string length in bson");let b=l.toUTF8(e,t,t+m-1,L);w=new Y(b),t=t+m}else if(T===Le){let m=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(m<4+4+4+1)throw new a("code_w_scope total size shorter minimum expected length");let b=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(b<=0||b>e.length-t||e[t+b-1]!==0)throw new a("bad string length in bson");let I=l.toUTF8(e,t,t+b-1,L);t=t+b;let z=t,_t=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24,Qe=Ot(e,z,s,!1);if(t=t+_t,m<4+4+_t+b)throw new a("code_w_scope total size is too short, truncating scope");if(m>4+4+_t+b)throw new a("code_w_scope total size is too long, clips outer document");w=new Y(I,Qe)}else if(T===hn){let m=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(m<=0||m>e.length-t||e[t+m-1]!==0)throw new a("bad string length in bson");if(f!=null&&f.utf8&&!Me(e,t,t+m-1))throw new a("Invalid UTF-8 string in BSON document");let b=l.toUTF8(e,t,t+m-1,!1);t=t+m;let I=l.allocate(12);I.set(e.subarray(t,t+12),0);let z=new k(I);t=t+12,w=new C(b,z)}else throw new a(`Detected unknown BSON type ${T.toString(16)} for fieldname "${d}"`);d==="__proto__"?Object.defineProperty(A,d,{value:w,writable:!0,enumerable:!0,configurable:!0}):A[d]=w}if(D!==t-$)throw n?new a("corrupt array bson"):new a("corrupt object bson");if(!R)return A;if(Je(A)){let T=Object.assign({},A);return delete T.$ref,delete T.$id,delete T.$db,new C(A.$ref,A.$id,A.$db,T)}return A}var It=/\x00/,Ne=new Set(["$db","$ref","$id","$clusterTime"]);function Dt(e,t,s,n){e[n++]=Ie;let r=l.encodeUTF8Into(e,t,n);n=n+r+1,e[n-1]=0;let o=l.encodeUTF8Into(e,s,n+4);return e[n+3]=o+1>>24&255,e[n+2]=o+1>>16&255,e[n+1]=o+1>>8&255,e[n]=o+1&255,n=n+4+o,e[n++]=0,n}var mt=new DataView(new ArrayBuffer(8),0,8),Zn=new Uint8Array(mt.buffer,0,4),dt=new Uint8Array(mt.buffer,0,8);function jt(e,t,s,n){let o=!Object.is(s,-0)&&Number.isSafeInteger(s)&&s<=At&&s>=$t?at:bt;o===at?mt.setInt32(0,s,!0):mt.setFloat64(0,s,!0);let c=o===at?Zn:dt;e[n++]=o;let g=l.encodeUTF8Into(e,t,n);return n=n+g,e[n++]=0,e.set(c,n),n+=c.byteLength,n}function zt(e,t,s,n){e[n++]=ie;let r=l.encodeUTF8Into(e,t,n);return n+=r,e[n++]=0,mt.setBigInt64(0,s,!0),e.set(dt,n),n+=dt.byteLength,n}function pt(e,t,s,n){e[n++]=se;let r=l.encodeUTF8Into(e,t,n);return n=n+r,e[n++]=0,n}function Ft(e,t,s,n){e[n++]=$e;let r=l.encodeUTF8Into(e,t,n);return n=n+r,e[n++]=0,e[n++]=s?1:0,n}function Mt(e,t,s,n){e[n++]=_e;let r=l.encodeUTF8Into(e,t,n);n=n+r,e[n++]=0;let o=y.fromNumber(s.getTime()),c=o.getLowBits(),g=o.getHighBits();return e[n++]=c&255,e[n++]=c>>8&255,e[n++]=c>>16&255,e[n++]=c>>24&255,e[n++]=g&255,e[n++]=g>>8&255,e[n++]=g>>16&255,e[n++]=g>>24&255,n}function xt(e,t,s,n){e[n++]=Et;let r=l.encodeUTF8Into(e,t,n);if(n=n+r,e[n++]=0,s.source&&s.source.match(It)!=null)throw new a("value "+s.source+" must not contain null bytes");return n=n+l.encodeUTF8Into(e,s.source,n),e[n++]=0,s.ignoreCase&&(e[n++]=105),s.global&&(e[n++]=115),s.multiline&&(e[n++]=109),e[n++]=0,n}function Jt(e,t,s,n){e[n++]=Et;let r=l.encodeUTF8Into(e,t,n);if(n=n+r,e[n++]=0,s.pattern.match(It)!=null)throw new a("pattern "+s.pattern+" must not contain null bytes");n=n+l.encodeUTF8Into(e,s.pattern,n),e[n++]=0;let o=s.options.split("").sort().join("");return n=n+l.encodeUTF8Into(e,o,n),e[n++]=0,n}function Ct(e,t,s,n){s===null?e[n++]=se:s._bsontype==="MinKey"?e[n++]=je:e[n++]=ze;let r=l.encodeUTF8Into(e,t,n);return n=n+r,e[n++]=0,n}function Ht(e,t,s,n){e[n++]=Ae;let r=l.encodeUTF8Into(e,t,n);n=n+r,e[n++]=0;let o=s.id;if(tt(o))for(let c=0;c<12;c++)e[n++]=o[c];else throw new a("object ["+JSON.stringify(s)+"] is not a valid ObjectId");return n}function Vt(e,t,s,n){e[n++]=ne;let r=l.encodeUTF8Into(e,t,n);n=n+r,e[n++]=0;let o=s.length;return e[n++]=o&255,e[n++]=o>>8&255,e[n++]=o>>16&255,e[n++]=o>>24&255,e[n++]=an,e.set(s,n),n=n+o,n}function Pt(e,t,s,n,r,o,c,g,i){if(i.has(s))throw new a("Cannot convert circular structure to BSON");i.add(s),e[n++]=Array.isArray(s)?de:ee;let S=l.encodeUTF8Into(e,t,n);n=n+S,e[n++]=0;let u=St(e,s,r,n,o+1,c,g,i);return i.delete(s),u}function Wt(e,t,s,n){e[n++]=De;let r=l.encodeUTF8Into(e,t,n);return n=n+r,e[n++]=0,e.set(s.bytes.subarray(0,16),n),n+16}function Yt(e,t,s,n){e[n++]=s._bsontype==="Long"?ie:Re;let r=l.encodeUTF8Into(e,t,n);n=n+r,e[n++]=0;let o=s.getLowBits(),c=s.getHighBits();return e[n++]=o&255,e[n++]=o>>8&255,e[n++]=o>>16&255,e[n++]=o>>24&255,e[n++]=c&255,e[n++]=c>>8&255,e[n++]=c>>16&255,e[n++]=c>>24&255,n}function kt(e,t,s,n){s=s.valueOf(),e[n++]=at;let r=l.encodeUTF8Into(e,t,n);return n=n+r,e[n++]=0,e[n++]=s&255,e[n++]=s>>8&255,e[n++]=s>>16&255,e[n++]=s>>24&255,n}function qt(e,t,s,n){e[n++]=bt;let r=l.encodeUTF8Into(e,t,n);return n=n+r,e[n++]=0,mt.setFloat64(0,s.value,!0),e.set(dt,n),n=n+8,n}function Zt(e,t,s,n){e[n++]=re;let r=l.encodeUTF8Into(e,t,n);n=n+r,e[n++]=0;let o=s.toString(),c=l.encodeUTF8Into(e,o,n+4)+1;return e[n]=c&255,e[n+1]=c>>8&255,e[n+2]=c>>16&255,e[n+3]=c>>24&255,n=n+4+c-1,e[n++]=0,n}function Kt(e,t,s,n,r=!1,o=0,c=!1,g=!0,i){if(s.scope&&typeof s.scope=="object"){e[n++]=Le;let S=l.encodeUTF8Into(e,t,n);n=n+S,e[n++]=0;let u=n,f=s.code;n=n+4;let h=l.encodeUTF8Into(e,f,n+4)+1;e[n]=h&255,e[n+1]=h>>8&255,e[n+2]=h>>16&255,e[n+3]=h>>24&255,e[n+4+h-1]=0,n=n+h+4;let N=St(e,s.scope,r,n,o+1,c,g,i);n=N-1;let p=N-u;e[u++]=p&255,e[u++]=p>>8&255,e[u++]=p>>16&255,e[u++]=p>>24&255,e[n++]=0}else{e[n++]=re;let S=l.encodeUTF8Into(e,t,n);n=n+S,e[n++]=0;let u=s.code.toString(),f=l.encodeUTF8Into(e,u,n+4)+1;e[n]=f&255,e[n+1]=f>>8&255,e[n+2]=f>>16&255,e[n+3]=f>>24&255,n=n+4+f-1,e[n++]=0}return n}function Gt(e,t,s,n){e[n++]=ne;let r=l.encodeUTF8Into(e,t,n);n=n+r,e[n++]=0;let o=s.buffer,c=s.position;return s.sub_type===_.SUBTYPE_BYTE_ARRAY&&(c=c+4),e[n++]=c&255,e[n++]=c>>8&255,e[n++]=c>>16&255,e[n++]=c>>24&255,e[n++]=s.sub_type,s.sub_type===_.SUBTYPE_BYTE_ARRAY&&(c=c-4,e[n++]=c&255,e[n++]=c>>8&255,e[n++]=c>>16&255,e[n++]=c>>24&255),e.set(o,n),n=n+s.position,n}function Xt(e,t,s,n){e[n++]=Ue;let r=l.encodeUTF8Into(e,t,n);n=n+r,e[n++]=0;let o=l.encodeUTF8Into(e,s.value,n+4)+1;return e[n]=o&255,e[n+1]=o>>8&255,e[n+2]=o>>16&255,e[n+3]=o>>24&255,n=n+4+o-1,e[n++]=0,n}function Qt(e,t,s,n,r,o,c){e[n++]=ee;let g=l.encodeUTF8Into(e,t,n);n=n+g,e[n++]=0;let i=n,S={$ref:s.collection||s.namespace,$id:s.oid};s.db!=null&&(S.$db=s.db),S=Object.assign(S,s.fields);let u=St(e,S,!1,n,r+1,o,!0,c),f=u-i;return e[i++]=f&255,e[i++]=f>>8&255,e[i++]=f>>16&255,e[i++]=f>>24&255,u}function St(e,t,s,n,r,o,c,g){if(g==null){if(t==null)return e[0]=5,e[1]=0,e[2]=0,e[3]=0,e[4]=0,5;if(Array.isArray(t))throw new a("serialize does not support an array as the root input");if(typeof t!="object")throw new a("serialize does not support non-object as the root input");if("_bsontype"in t&&typeof t._bsontype=="string")throw new a("BSON types cannot be serialized as a document");if(ct(t)||lt(t)||tt(t)||vt(t))throw new a("date, regexp, typedarray, and arraybuffer cannot be BSON documents");g=new Set}g.add(t);let i=n+4;if(Array.isArray(t))for(let u=0;u>8&255,e[n++]=S>>16&255,e[n++]=S>>24&255,i}function Kn(e){return e!=null&&typeof e=="object"&&"_bsontype"in e&&typeof e._bsontype=="string"}var Gn={$oid:k,$binary:_,$uuid:_,$symbol:it,$numberInt:X,$numberDecimal:nt,$numberDouble:G,$numberLong:y,$minKey:rt,$maxKey:st,$regex:q,$regularExpression:q,$timestamp:Q};function Ve(e,t={}){if(typeof e=="number"){let n=e<=At&&e>=$t,r=e<=Oe&&e>=be;if(t.relaxed||t.legacy)return e;if(Number.isInteger(e)&&!Object.is(e,-0)){if(n)return new X(e);if(r)return t.useBigInt64?BigInt(e):y.fromNumber(e)}return new G(e)}if(e==null||typeof e!="object")return e;if(e.$undefined)return null;let s=Object.keys(e).filter(n=>n.startsWith("$")&&e[n]!=null);for(let n=0;nc.startsWith("$")),o=!0;if(r.forEach(c=>{["$ref","$id","$db"].indexOf(c)===-1&&(o=!1)}),o)return C.fromExtendedJSON(n)}return e}function Xn(e,t){return e.map((s,n)=>{t.seenObjects.push({propertyName:`index ${n}`,obj:null});try{return V(s,t)}finally{t.seenObjects.pop()}})}function Be(e){let t=e.toISOString();return e.getUTCMilliseconds()!==0?t:t.slice(0,-5)+"Z"}function V(e,t){if(e instanceof Map||te(e)){let s=Object.create(null);for(let[n,r]of e){if(typeof n!="string")throw new a("Can only serialize maps with string keys");s[n]=r}return V(s,t)}if((typeof e=="object"||typeof e=="function")&&e!==null){let s=t.seenObjects.findIndex(n=>n.obj===e);if(s!==-1){let n=t.seenObjects.map(u=>u.propertyName),r=n.slice(0,s).map(u=>`${u} -> `).join(""),o=n[s],c=" -> "+n.slice(s+1,n.length-1).map(u=>`${u} -> `).join(""),g=n[n.length-1],i=" ".repeat(r.length+o.length/2),S="-".repeat(c.length+(o.length+g.length)/2-1);throw new a(`Converting circular structure to EJSON: + ${r}${o}${c}${g} + ${i}\\${S}/`)}t.seenObjects[t.seenObjects.length-1].obj=e}if(Array.isArray(e))return Xn(e,t);if(e===void 0)return null;if(e instanceof Date||ct(e)){let s=e.getTime(),n=s>-1&&s<2534023188e5;return t.legacy?t.relaxed&&n?{$date:e.getTime()}:{$date:Be(e)}:t.relaxed&&n?{$date:Be(e)}:{$date:{$numberLong:e.getTime().toString()}}}if(typeof e=="number"&&(!t.relaxed||!isFinite(e))){if(Number.isInteger(e)&&!Object.is(e,-0)){if(e>=$t&&e<=At)return{$numberInt:e.toString()};if(e>=be&&e<=Oe)return{$numberLong:e.toString()}}return{$numberDouble:Object.is(e,-0)?"-0.0":e.toString()}}if(typeof e=="bigint")return t.relaxed?Number(BigInt.asIntN(64,e)):{$numberLong:BigInt.asIntN(64,e).toString()};if(e instanceof RegExp||lt(e)){let s=e.flags;if(s===void 0){let r=e.toString().match(/[gimuy]*$/);r&&(s=r[0])}return new q(e.source,s).toExtendedJSON(t)}return e!=null&&typeof e=="object"?vn(e,t):e}var Qn={Binary:e=>new _(e.value(),e.sub_type),Code:e=>new Y(e.code,e.scope),DBRef:e=>new C(e.collection||e.namespace,e.oid,e.db,e.fields),Decimal128:e=>new nt(e.bytes),Double:e=>new G(e.value),Int32:e=>new X(e.value),Long:e=>y.fromBits(e.low!=null?e.low:e.low_,e.low!=null?e.high:e.high_,e.low!=null?e.unsigned:e.unsigned_),MaxKey:()=>new st,MinKey:()=>new rt,ObjectId:e=>new k(e),BSONRegExp:e=>new q(e.pattern,e.options),BSONSymbol:e=>new it(e.value),Timestamp:e=>Q.fromBits(e.low,e.high)};function vn(e,t){if(e==null||typeof e!="object")throw new a("not an object instance");let s=e._bsontype;if(typeof s>"u"){let n={};for(let r of Object.keys(e)){t.seenObjects.push({propertyName:r,obj:null});try{let o=V(e[r],t);r==="__proto__"?Object.defineProperty(n,r,{value:o,writable:!0,enumerable:!0,configurable:!0}):n[r]=o}finally{t.seenObjects.pop()}}return n}else{if(e!=null&&typeof e=="object"&&typeof e._bsontype=="string"&&e[Symbol.for("@@mdb.bson.version")]!==et)throw new P;if(Kn(e)){let n=e;if(typeof n.toExtendedJSON!="function"){let r=Qn[e._bsontype];if(!r)throw new a("Unrecognized or invalid _bsontype: "+e._bsontype);n=r(n)}return s==="Code"&&n.scope?n=new Y(n.code,V(n.scope,t)):s==="DBRef"&&n.oid&&(n=new C(V(n.collection,t),V(n.oid,t),V(n.db,t),V(n.fields,t))),n.toExtendedJSON(t)}else throw new a("_bsontype must be a string, but was: "+typeof s)}}function Pe(e,t){let s={useBigInt64:t?.useBigInt64??!1,relaxed:t?.relaxed??!0,legacy:t?.legacy??!1};return JSON.parse(e,(n,r)=>{if(n.indexOf("\0")!==-1)throw new a(`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(n)}`);return Ve(r,s)})}function We(e,t,s,n){s!=null&&typeof s=="object"&&(n=s,s=0),t!=null&&typeof t=="object"&&!Array.isArray(t)&&(n=t,t=void 0,s=0);let r=Object.assign({relaxed:!0,legacy:!1},n,{seenObjects:[{propertyName:"(root)",obj:null}]}),o=V(e,r);return JSON.stringify(o,t,s)}function ts(e,t){return t=t||{},JSON.parse(We(e,t))}function es(e,t){return t=t||{},Pe(JSON.stringify(e),t)}var ot=Object.create(null);ot.parse=Pe;ot.stringify=We;ot.serialize=ts;ot.deserialize=es;Object.freeze(ot);var Ye=1024*1024*17,K=l.allocate(Ye);function ke(e){K.lengthss,toJson:()=>rs});var ss=oe().deserialize,rs=oe().EJSON.deserialize;return fn(is);})(); diff --git a/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js b/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js index b2e9f29892..ff8d7265c6 100644 --- a/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js +++ b/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js @@ -1,3560 +1,4 @@ -"use strict"; -var helpers = (() => { - var __create = Object.create; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __getProtoOf = Object.getPrototypeOf; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { - get: (a, b) => (typeof require !== "undefined" ? require : a)[b] - }) : x)(function(x) { - if (typeof require !== "undefined") - return require.apply(this, arguments); - throw Error('Dynamic require of "' + x + '" is not supported'); - }); - var __esm = (fn, res) => function __init() { - return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; - }; - var __commonJS = (cb, mod) => function __require2() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; - }; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod - )); - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - - // ../../node_modules/dayjs/dayjs.min.js - var require_dayjs_min = __commonJS({ - "../../node_modules/dayjs/dayjs.min.js"(exports, module) { - !function(t, e) { - "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); - }(exports, function() { - "use strict"; - var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { - var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; - return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; - } }, m = function(t2, e2, n2) { - var r2 = String(t2); - return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; - }, v = { s: m, z: function(t2) { - var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; - return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); - }, m: function t2(e2, n2) { - if (e2.date() < n2.date()) - return -t2(n2, e2); - var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c); - return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); - }, a: function(t2) { - return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); - }, p: function(t2) { - return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); - }, u: function(t2) { - return void 0 === t2; - } }, g = "en", D = {}; - D[g] = M; - var p = "$isDayjsObject", S = function(t2) { - return t2 instanceof _ || !(!t2 || !t2[p]); - }, w = function t2(e2, n2, r2) { - var i2; - if (!e2) - return g; - if ("string" == typeof e2) { - var s2 = e2.toLowerCase(); - D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); - var u2 = e2.split("-"); - if (!i2 && u2.length > 1) - return t2(u2[0]); - } else { - var a2 = e2.name; - D[a2] = e2, i2 = a2; - } - return !r2 && i2 && (g = i2), i2 || !r2 && g; - }, O = function(t2, e2) { - if (S(t2)) - return t2.clone(); - var n2 = "object" == typeof e2 ? e2 : {}; - return n2.date = t2, n2.args = arguments, new _(n2); - }, b = v; - b.l = w, b.i = S, b.w = function(t2, e2) { - return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); - }; - var _ = function() { - function M2(t2) { - this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true; - } - var m2 = M2.prototype; - return m2.parse = function(t2) { - this.$d = function(t3) { - var e2 = t3.date, n2 = t3.utc; - if (null === e2) - return /* @__PURE__ */ new Date(NaN); - if (b.u(e2)) - return /* @__PURE__ */ new Date(); - if (e2 instanceof Date) - return new Date(e2); - if ("string" == typeof e2 && !/Z$/i.test(e2)) { - var r2 = e2.match($); - if (r2) { - var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); - return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); - } - } - return new Date(e2); - }(t2), this.init(); - }, m2.init = function() { - var t2 = this.$d; - this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); - }, m2.$utils = function() { - return b; - }, m2.isValid = function() { - return !(this.$d.toString() === l); - }, m2.isSame = function(t2, e2) { - var n2 = O(t2); - return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); - }, m2.isAfter = function(t2, e2) { - return O(t2) < this.startOf(e2); - }, m2.isBefore = function(t2, e2) { - return this.endOf(e2) < O(t2); - }, m2.$g = function(t2, e2, n2) { - return b.u(t2) ? this[e2] : this.set(n2, t2); - }, m2.unix = function() { - return Math.floor(this.valueOf() / 1e3); - }, m2.valueOf = function() { - return this.$d.getTime(); - }, m2.startOf = function(t2, e2) { - var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) { - var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); - return r2 ? i2 : i2.endOf(a); - }, $2 = function(t3, e3) { - return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); - }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); - switch (f2) { - case h: - return r2 ? l2(1, 0) : l2(31, 11); - case c: - return r2 ? l2(1, M3) : l2(0, M3 + 1); - case o: - var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; - return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); - case a: - case d: - return $2(v2 + "Hours", 0); - case u: - return $2(v2 + "Minutes", 1); - case s: - return $2(v2 + "Seconds", 2); - case i: - return $2(v2 + "Milliseconds", 3); - default: - return this.clone(); - } - }, m2.endOf = function(t2) { - return this.startOf(t2, false); - }, m2.$set = function(t2, e2) { - var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; - if (o2 === c || o2 === h) { - var y2 = this.clone().set(d, 1); - y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; - } else - l2 && this.$d[l2]($2); - return this.init(), this; - }, m2.set = function(t2, e2) { - return this.clone().$set(t2, e2); - }, m2.get = function(t2) { - return this[b.p(t2)](); - }, m2.add = function(r2, f2) { - var d2, l2 = this; - r2 = Number(r2); - var $2 = b.p(f2), y2 = function(t2) { - var e2 = O(l2); - return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); - }; - if ($2 === c) - return this.set(c, this.$M + r2); - if ($2 === h) - return this.set(h, this.$y + r2); - if ($2 === a) - return y2(1); - if ($2 === o) - return y2(7); - var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; - return b.w(m3, this); - }, m2.subtract = function(t2, e2) { - return this.add(-1 * t2, e2); - }, m2.format = function(t2) { - var e2 = this, n2 = this.$locale(); - if (!this.isValid()) - return n2.invalidDate || l; - var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = function(t3, n3, i3, s3) { - return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); - }, d2 = function(t3) { - return b.s(s2 % 12 || 12, t3, "0"); - }, $2 = f2 || function(t3, e3, n3) { - var r3 = t3 < 12 ? "AM" : "PM"; - return n3 ? r3.toLowerCase() : r3; - }; - return r2.replace(y, function(t3, r3) { - return r3 || function(t4) { - switch (t4) { - case "YY": - return String(e2.$y).slice(-2); - case "YYYY": - return b.s(e2.$y, 4, "0"); - case "M": - return a2 + 1; - case "MM": - return b.s(a2 + 1, 2, "0"); - case "MMM": - return h2(n2.monthsShort, a2, c2, 3); - case "MMMM": - return h2(c2, a2); - case "D": - return e2.$D; - case "DD": - return b.s(e2.$D, 2, "0"); - case "d": - return String(e2.$W); - case "dd": - return h2(n2.weekdaysMin, e2.$W, o2, 2); - case "ddd": - return h2(n2.weekdaysShort, e2.$W, o2, 3); - case "dddd": - return o2[e2.$W]; - case "H": - return String(s2); - case "HH": - return b.s(s2, 2, "0"); - case "h": - return d2(1); - case "hh": - return d2(2); - case "a": - return $2(s2, u2, true); - case "A": - return $2(s2, u2, false); - case "m": - return String(u2); - case "mm": - return b.s(u2, 2, "0"); - case "s": - return String(e2.$s); - case "ss": - return b.s(e2.$s, 2, "0"); - case "SSS": - return b.s(e2.$ms, 3, "0"); - case "Z": - return i2; - } - return null; - }(t3) || i2.replace(":", ""); - }); - }, m2.utcOffset = function() { - return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); - }, m2.diff = function(r2, d2, l2) { - var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() { - return b.m(y2, m3); - }; - switch (M3) { - case h: - $2 = D2() / 12; - break; - case c: - $2 = D2(); - break; - case f: - $2 = D2() / 3; - break; - case o: - $2 = (g2 - v2) / 6048e5; - break; - case a: - $2 = (g2 - v2) / 864e5; - break; - case u: - $2 = g2 / n; - break; - case s: - $2 = g2 / e; - break; - case i: - $2 = g2 / t; - break; - default: - $2 = g2; - } - return l2 ? $2 : b.a($2); - }, m2.daysInMonth = function() { - return this.endOf(c).$D; - }, m2.$locale = function() { - return D[this.$L]; - }, m2.locale = function(t2, e2) { - if (!t2) - return this.$L; - var n2 = this.clone(), r2 = w(t2, e2, true); - return r2 && (n2.$L = r2), n2; - }, m2.clone = function() { - return b.w(this.$d, this); - }, m2.toDate = function() { - return new Date(this.valueOf()); - }, m2.toJSON = function() { - return this.isValid() ? this.toISOString() : null; - }, m2.toISOString = function() { - return this.$d.toISOString(); - }, m2.toString = function() { - return this.$d.toUTCString(); - }, M2; - }(), k = _.prototype; - return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) { - k[t2[1]] = function(e2) { - return this.$g(e2, t2[0], t2[1]); - }; - }), O.extend = function(t2, e2) { - return t2.$i || (t2(e2, _, O), t2.$i = true), O; - }, O.locale = w, O.isDayjs = S, O.unix = function(t2) { - return O(1e3 * t2); - }, O.en = D[g], O.Ls = D, O.p = {}, O; - }); - } - }); - - // ../../node_modules/dayjs/plugin/duration.js - var require_duration = __commonJS({ - "../../node_modules/dayjs/plugin/duration.js"(exports, module) { - !function(t, s) { - "object" == typeof exports && "undefined" != typeof module ? module.exports = s() : "function" == typeof define && define.amd ? define(s) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_duration = s(); - }(exports, function() { - "use strict"; - var t, s, n = 1e3, i = 6e4, e = 36e5, r = 864e5, o = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, u = 31536e6, d = 2628e6, a = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/, h = { years: u, months: d, days: r, hours: e, minutes: i, seconds: n, milliseconds: 1, weeks: 6048e5 }, c = function(t2) { - return t2 instanceof g; - }, f = function(t2, s2, n2) { - return new g(t2, n2, s2.$l); - }, m = function(t2) { - return s.p(t2) + "s"; - }, l = function(t2) { - return t2 < 0; - }, $ = function(t2) { - return l(t2) ? Math.ceil(t2) : Math.floor(t2); - }, y = function(t2) { - return Math.abs(t2); - }, v = function(t2, s2) { - return t2 ? l(t2) ? { negative: true, format: "" + y(t2) + s2 } : { negative: false, format: "" + t2 + s2 } : { negative: false, format: "" }; - }, g = function() { - function l2(t2, s2, n2) { - var i2 = this; - if (this.$d = {}, this.$l = n2, void 0 === t2 && (this.$ms = 0, this.parseFromMilliseconds()), s2) - return f(t2 * h[m(s2)], this); - if ("number" == typeof t2) - return this.$ms = t2, this.parseFromMilliseconds(), this; - if ("object" == typeof t2) - return Object.keys(t2).forEach(function(s3) { - i2.$d[m(s3)] = t2[s3]; - }), this.calMilliseconds(), this; - if ("string" == typeof t2) { - var e2 = t2.match(a); - if (e2) { - var r2 = e2.slice(2).map(function(t3) { - return null != t3 ? Number(t3) : 0; - }); - return this.$d.years = r2[0], this.$d.months = r2[1], this.$d.weeks = r2[2], this.$d.days = r2[3], this.$d.hours = r2[4], this.$d.minutes = r2[5], this.$d.seconds = r2[6], this.calMilliseconds(), this; - } - } - return this; - } - var y2 = l2.prototype; - return y2.calMilliseconds = function() { - var t2 = this; - this.$ms = Object.keys(this.$d).reduce(function(s2, n2) { - return s2 + (t2.$d[n2] || 0) * h[n2]; - }, 0); - }, y2.parseFromMilliseconds = function() { - var t2 = this.$ms; - this.$d.years = $(t2 / u), t2 %= u, this.$d.months = $(t2 / d), t2 %= d, this.$d.days = $(t2 / r), t2 %= r, this.$d.hours = $(t2 / e), t2 %= e, this.$d.minutes = $(t2 / i), t2 %= i, this.$d.seconds = $(t2 / n), t2 %= n, this.$d.milliseconds = t2; - }, y2.toISOString = function() { - var t2 = v(this.$d.years, "Y"), s2 = v(this.$d.months, "M"), n2 = +this.$d.days || 0; - this.$d.weeks && (n2 += 7 * this.$d.weeks); - var i2 = v(n2, "D"), e2 = v(this.$d.hours, "H"), r2 = v(this.$d.minutes, "M"), o2 = this.$d.seconds || 0; - this.$d.milliseconds && (o2 += this.$d.milliseconds / 1e3, o2 = Math.round(1e3 * o2) / 1e3); - var u2 = v(o2, "S"), d2 = t2.negative || s2.negative || i2.negative || e2.negative || r2.negative || u2.negative, a2 = e2.format || r2.format || u2.format ? "T" : "", h2 = (d2 ? "-" : "") + "P" + t2.format + s2.format + i2.format + a2 + e2.format + r2.format + u2.format; - return "P" === h2 || "-P" === h2 ? "P0D" : h2; - }, y2.toJSON = function() { - return this.toISOString(); - }, y2.format = function(t2) { - var n2 = t2 || "YYYY-MM-DDTHH:mm:ss", i2 = { Y: this.$d.years, YY: s.s(this.$d.years, 2, "0"), YYYY: s.s(this.$d.years, 4, "0"), M: this.$d.months, MM: s.s(this.$d.months, 2, "0"), D: this.$d.days, DD: s.s(this.$d.days, 2, "0"), H: this.$d.hours, HH: s.s(this.$d.hours, 2, "0"), m: this.$d.minutes, mm: s.s(this.$d.minutes, 2, "0"), s: this.$d.seconds, ss: s.s(this.$d.seconds, 2, "0"), SSS: s.s(this.$d.milliseconds, 3, "0") }; - return n2.replace(o, function(t3, s2) { - return s2 || String(i2[t3]); - }); - }, y2.as = function(t2) { - return this.$ms / h[m(t2)]; - }, y2.get = function(t2) { - var s2 = this.$ms, n2 = m(t2); - return "milliseconds" === n2 ? s2 %= 1e3 : s2 = "weeks" === n2 ? $(s2 / h[n2]) : this.$d[n2], s2 || 0; - }, y2.add = function(t2, s2, n2) { - var i2; - return i2 = s2 ? t2 * h[m(s2)] : c(t2) ? t2.$ms : f(t2, this).$ms, f(this.$ms + i2 * (n2 ? -1 : 1), this); - }, y2.subtract = function(t2, s2) { - return this.add(t2, s2, true); - }, y2.locale = function(t2) { - var s2 = this.clone(); - return s2.$l = t2, s2; - }, y2.clone = function() { - return f(this.$ms, this); - }, y2.humanize = function(s2) { - return t().add(this.$ms, "ms").locale(this.$l).fromNow(!s2); - }, y2.valueOf = function() { - return this.asMilliseconds(); - }, y2.milliseconds = function() { - return this.get("milliseconds"); - }, y2.asMilliseconds = function() { - return this.as("milliseconds"); - }, y2.seconds = function() { - return this.get("seconds"); - }, y2.asSeconds = function() { - return this.as("seconds"); - }, y2.minutes = function() { - return this.get("minutes"); - }, y2.asMinutes = function() { - return this.as("minutes"); - }, y2.hours = function() { - return this.get("hours"); - }, y2.asHours = function() { - return this.as("hours"); - }, y2.days = function() { - return this.get("days"); - }, y2.asDays = function() { - return this.as("days"); - }, y2.weeks = function() { - return this.get("weeks"); - }, y2.asWeeks = function() { - return this.as("weeks"); - }, y2.months = function() { - return this.get("months"); - }, y2.asMonths = function() { - return this.as("months"); - }, y2.years = function() { - return this.get("years"); - }, y2.asYears = function() { - return this.as("years"); - }, l2; - }(), p = function(t2, s2, n2) { - return t2.add(s2.years() * n2, "y").add(s2.months() * n2, "M").add(s2.days() * n2, "d").add(s2.hours() * n2, "h").add(s2.minutes() * n2, "m").add(s2.seconds() * n2, "s").add(s2.milliseconds() * n2, "ms"); - }; - return function(n2, i2, e2) { - t = e2, s = e2().$utils(), e2.duration = function(t2, s2) { - var n3 = e2.locale(); - return f(t2, { $l: n3 }, s2); - }, e2.isDuration = c; - var r2 = i2.prototype.add, o2 = i2.prototype.subtract; - i2.prototype.add = function(t2, s2) { - return c(t2) ? p(this, t2, 1) : r2.bind(this)(t2, s2); - }, i2.prototype.subtract = function(t2, s2) { - return c(t2) ? p(this, t2, -1) : o2.bind(this)(t2, s2); - }; - }; - }); - } - }); - - // ../../node_modules/dayjs/plugin/advancedFormat.js - var require_advancedFormat = __commonJS({ - "../../node_modules/dayjs/plugin/advancedFormat.js"(exports, module) { - !function(e, t) { - "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_advancedFormat = t(); - }(exports, function() { - "use strict"; - return function(e, t) { - var r = t.prototype, n = r.format; - r.format = function(e2) { - var t2 = this, r2 = this.$locale(); - if (!this.isValid()) - return n.bind(this)(e2); - var s = this.$utils(), a = (e2 || "YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g, function(e3) { - switch (e3) { - case "Q": - return Math.ceil((t2.$M + 1) / 3); - case "Do": - return r2.ordinal(t2.$D); - case "gggg": - return t2.weekYear(); - case "GGGG": - return t2.isoWeekYear(); - case "wo": - return r2.ordinal(t2.week(), "W"); - case "w": - case "ww": - return s.s(t2.week(), "w" === e3 ? 1 : 2, "0"); - case "W": - case "WW": - return s.s(t2.isoWeek(), "W" === e3 ? 1 : 2, "0"); - case "k": - case "kk": - return s.s(String(0 === t2.$H ? 24 : t2.$H), "k" === e3 ? 1 : 2, "0"); - case "X": - return Math.floor(t2.$d.getTime() / 1e3); - case "x": - return t2.$d.getTime(); - case "z": - return "[" + t2.offsetName() + "]"; - case "zzz": - return "[" + t2.offsetName("long") + "]"; - default: - return e3; - } - }); - return n.bind(this)(a); - }; - }; - }); - } - }); - - // ../../node_modules/dayjs/plugin/isoWeek.js - var require_isoWeek = __commonJS({ - "../../node_modules/dayjs/plugin/isoWeek.js"(exports, module) { - !function(e, t) { - "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_isoWeek = t(); - }(exports, function() { - "use strict"; - var e = "day"; - return function(t, i, s) { - var a = function(t2) { - return t2.add(4 - t2.isoWeekday(), e); - }, d = i.prototype; - d.isoWeekYear = function() { - return a(this).year(); - }, d.isoWeek = function(t2) { - if (!this.$utils().u(t2)) - return this.add(7 * (t2 - this.isoWeek()), e); - var i2, d2, n2, o, r = a(this), u = (i2 = this.isoWeekYear(), d2 = this.$u, n2 = (d2 ? s.utc : s)().year(i2).startOf("year"), o = 4 - n2.isoWeekday(), n2.isoWeekday() > 4 && (o += 7), n2.add(o, e)); - return r.diff(u, "week") + 1; - }, d.isoWeekday = function(e2) { - return this.$utils().u(e2) ? this.day() || 7 : this.day(this.day() % 7 ? e2 : e2 - 7); - }; - var n = d.startOf; - d.startOf = function(e2, t2) { - var i2 = this.$utils(), s2 = !!i2.u(t2) || t2; - return "isoweek" === i2.p(e2) ? s2 ? this.date(this.date() - (this.isoWeekday() - 1)).startOf("day") : this.date(this.date() - 1 - (this.isoWeekday() - 1) + 7).endOf("day") : n.bind(this)(e2, t2); - }; - }; - }); - } - }); - - // ../../node_modules/dayjs/plugin/weekYear.js - var require_weekYear = __commonJS({ - "../../node_modules/dayjs/plugin/weekYear.js"(exports, module) { - !function(e, t) { - "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_weekYear = t(); - }(exports, function() { - "use strict"; - return function(e, t) { - t.prototype.weekYear = function() { - var e2 = this.month(), t2 = this.week(), n = this.year(); - return 1 === t2 && 11 === e2 ? n + 1 : 0 === e2 && t2 >= 52 ? n - 1 : n; - }; - }; - }); - } - }); - - // ../../node_modules/dayjs/plugin/weekOfYear.js - var require_weekOfYear = __commonJS({ - "../../node_modules/dayjs/plugin/weekOfYear.js"(exports, module) { - !function(e, t) { - "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_weekOfYear = t(); - }(exports, function() { - "use strict"; - var e = "week", t = "year"; - return function(i, n, r) { - var f = n.prototype; - f.week = function(i2) { - if (void 0 === i2 && (i2 = null), null !== i2) - return this.add(7 * (i2 - this.week()), "day"); - var n2 = this.$locale().yearStart || 1; - if (11 === this.month() && this.date() > 25) { - var f2 = r(this).startOf(t).add(1, t).date(n2), s = r(this).endOf(e); - if (f2.isBefore(s)) - return 1; - } - var a = r(this).startOf(t).date(n2).startOf(e).subtract(1, "millisecond"), o = this.diff(a, e, true); - return o < 0 ? r(this).startOf("week").week() : Math.ceil(o); - }, f.weeks = function(e2) { - return void 0 === e2 && (e2 = null), this.week(e2); - }; - }; - }); - } - }); - - // ../../node_modules/dayjs/plugin/relativeTime.js - var require_relativeTime = __commonJS({ - "../../node_modules/dayjs/plugin/relativeTime.js"(exports, module) { - !function(r, e) { - "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (r = "undefined" != typeof globalThis ? globalThis : r || self).dayjs_plugin_relativeTime = e(); - }(exports, function() { - "use strict"; - return function(r, e, t) { - r = r || {}; - var n = e.prototype, o = { future: "in %s", past: "%s ago", s: "a few seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", M: "a month", MM: "%d months", y: "a year", yy: "%d years" }; - function i(r2, e2, t2, o2) { - return n.fromToBase(r2, e2, t2, o2); - } - t.en.relativeTime = o, n.fromToBase = function(e2, n2, i2, d2, u) { - for (var f, a, s, l = i2.$locale().relativeTime || o, h = r.thresholds || [{ l: "s", r: 44, d: "second" }, { l: "m", r: 89 }, { l: "mm", r: 44, d: "minute" }, { l: "h", r: 89 }, { l: "hh", r: 21, d: "hour" }, { l: "d", r: 35 }, { l: "dd", r: 25, d: "day" }, { l: "M", r: 45 }, { l: "MM", r: 10, d: "month" }, { l: "y", r: 17 }, { l: "yy", d: "year" }], m = h.length, c = 0; c < m; c += 1) { - var y = h[c]; - y.d && (f = d2 ? t(e2).diff(i2, y.d, true) : i2.diff(e2, y.d, true)); - var p = (r.rounding || Math.round)(Math.abs(f)); - if (s = f > 0, p <= y.r || !y.r) { - p <= 1 && c > 0 && (y = h[c - 1]); - var v = l[y.l]; - u && (p = u("" + p)), a = "string" == typeof v ? v.replace("%d", p) : v(p, n2, y.l, s); - break; - } - } - if (n2) - return a; - var M = s ? l.future : l.past; - return "function" == typeof M ? M(a) : M.replace("%s", a); - }, n.to = function(r2, e2) { - return i(r2, e2, this, true); - }, n.from = function(r2, e2) { - return i(r2, e2, this); - }; - var d = function(r2) { - return r2.$u ? t.utc() : t(); - }; - n.toNow = function(r2) { - return this.to(d(this), r2); - }, n.fromNow = function(r2) { - return this.from(d(this), r2); - }; - }; - }); - } - }); - - // ../../node_modules/dayjs/plugin/utc.js - var require_utc = __commonJS({ - "../../node_modules/dayjs/plugin/utc.js"(exports, module) { - !function(t, i) { - "object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_utc = i(); - }(exports, function() { - "use strict"; - var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g; - return function(s, f, n) { - var u = f.prototype; - n.utc = function(t2) { - var i2 = { date: t2, utc: true, args: arguments }; - return new f(i2); - }, u.utc = function(i2) { - var e2 = n(this.toDate(), { locale: this.$L, utc: true }); - return i2 ? e2.add(this.utcOffset(), t) : e2; - }, u.local = function() { - return n(this.toDate(), { locale: this.$L, utc: false }); - }; - var o = u.parse; - u.parse = function(t2) { - t2.utc && (this.$u = true), this.$utils().u(t2.$offset) || (this.$offset = t2.$offset), o.call(this, t2); - }; - var r = u.init; - u.init = function() { - if (this.$u) { - var t2 = this.$d; - this.$y = t2.getUTCFullYear(), this.$M = t2.getUTCMonth(), this.$D = t2.getUTCDate(), this.$W = t2.getUTCDay(), this.$H = t2.getUTCHours(), this.$m = t2.getUTCMinutes(), this.$s = t2.getUTCSeconds(), this.$ms = t2.getUTCMilliseconds(); - } else - r.call(this); - }; - var a = u.utcOffset; - u.utcOffset = function(s2, f2) { - var n2 = this.$utils().u; - if (n2(s2)) - return this.$u ? 0 : n2(this.$offset) ? a.call(this) : this.$offset; - if ("string" == typeof s2 && (s2 = function(t2) { - void 0 === t2 && (t2 = ""); - var s3 = t2.match(i); - if (!s3) - return null; - var f3 = ("" + s3[0]).match(e) || ["-", 0, 0], n3 = f3[0], u3 = 60 * +f3[1] + +f3[2]; - return 0 === u3 ? 0 : "+" === n3 ? u3 : -u3; - }(s2), null === s2)) - return this; - var u2 = Math.abs(s2) <= 16 ? 60 * s2 : s2, o2 = this; - if (f2) - return o2.$offset = u2, o2.$u = 0 === s2, o2; - if (0 !== s2) { - var r2 = this.$u ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset(); - (o2 = this.local().add(u2 + r2, t)).$offset = u2, o2.$x.$localOffset = r2; - } else - o2 = this.utc(); - return o2; - }; - var h = u.format; - u.format = function(t2) { - var i2 = t2 || (this.$u ? "YYYY-MM-DDTHH:mm:ss[Z]" : ""); - return h.call(this, i2); - }, u.valueOf = function() { - var t2 = this.$utils().u(this.$offset) ? 0 : this.$offset + (this.$x.$localOffset || this.$d.getTimezoneOffset()); - return this.$d.valueOf() - 6e4 * t2; - }, u.isUTC = function() { - return !!this.$u; - }, u.toISOString = function() { - return this.toDate().toISOString(); - }, u.toString = function() { - return this.toDate().toUTCString(); - }; - var l = u.toDate; - u.toDate = function(t2) { - return "s" === t2 && this.$offset ? n(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate() : l.call(this); - }; - var c = u.diff; - u.diff = function(t2, i2, e2) { - if (t2 && this.$u === t2.$u) - return c.call(this, t2, i2, e2); - var s2 = this.local(), f2 = n(t2).local(); - return c.call(s2, f2, i2, e2); - }; - }; - }); - } - }); - - // ../../node_modules/dayjs/plugin/timezone.js - var require_timezone = __commonJS({ - "../../node_modules/dayjs/plugin/timezone.js"(exports, module) { - !function(t, e) { - "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_timezone = e(); - }(exports, function() { - "use strict"; - var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {}; - return function(n, i, o) { - var r, a = function(t2, n2, i2) { - void 0 === i2 && (i2 = {}); - var o2 = new Date(t2), r2 = function(t3, n3) { - void 0 === n3 && (n3 = {}); - var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3]; - return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3; - }(n2, i2); - return r2.formatToParts(o2); - }, u = function(e2, n2) { - for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) { - var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2]; - c >= 0 && (r2[c] = parseInt(m, 10)); - } - var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2; - return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4; - }, f = i.prototype; - f.tz = function(t2, e2) { - void 0 === t2 && (t2 = r); - var n2 = this.utcOffset(), i2 = this.toDate(), a2 = i2.toLocaleString("en-US", { timeZone: t2 }), u2 = Math.round((i2 - new Date(a2)) / 1e3 / 60), f2 = o(a2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(15 * -Math.round(i2.getTimezoneOffset() / 15) - u2, true); - if (e2) { - var s2 = f2.utcOffset(); - f2 = f2.add(n2 - s2, "minute"); - } - return f2.$x.$timezone = t2, f2; - }, f.offsetName = function(t2) { - var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find(function(t3) { - return "timezonename" === t3.type.toLowerCase(); - }); - return n2 && n2.value; - }; - var s = f.startOf; - f.startOf = function(t2, e2) { - if (!this.$x || !this.$x.$timezone) - return s.call(this, t2, e2); - var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L }); - return s.call(n2, t2, e2).tz(this.$x.$timezone, true); - }, o.tz = function(t2, e2, n2) { - var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2); - if ("string" != typeof t2) - return o(t2).tz(a2); - var s2 = function(t3, e3, n3) { - var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3); - if (e3 === o2) - return [i3, e3]; - var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3); - return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)]; - }(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c); - return d.$x.$timezone = a2, d; - }, o.tz.guess = function() { - return Intl.DateTimeFormat().resolvedOptions().timeZone; - }, o.tz.setDefault = function(t2) { - r = t2; - }; - }; - }); - } - }); - - // ../string-templates/src/helpers/date.js - var require_date = __commonJS({ - "../string-templates/src/helpers/date.js"(exports, module) { - var dayjs = require_dayjs_min(); - dayjs.extend(require_duration()); - dayjs.extend(require_advancedFormat()); - dayjs.extend(require_isoWeek()); - dayjs.extend(require_weekYear()); - dayjs.extend(require_weekOfYear()); - dayjs.extend(require_relativeTime()); - dayjs.extend(require_utc()); - dayjs.extend(require_timezone()); - function isOptions(val) { - return typeof val === "object" && typeof val.hash === "object"; - } - function isApp(thisArg) { - return typeof thisArg === "object" && typeof thisArg.options === "object" && typeof thisArg.app === "object"; - } - function getContext(thisArg, locals, options) { - if (isOptions(thisArg)) { - return getContext({}, locals, thisArg); - } - if (isOptions(locals)) { - return getContext(thisArg, options, locals); - } - const appContext = isApp(thisArg) ? thisArg.context : {}; - options = options || {}; - if (!isOptions(options)) { - locals = Object.assign({}, locals, options); - } - if (isOptions(options) && options.hash.root === true) { - locals = Object.assign({}, options.data.root, locals); - } - let context = Object.assign({}, appContext, locals, options.hash); - if (!isApp(thisArg)) { - context = Object.assign({}, thisArg, context); - } - if (isApp(thisArg) && thisArg.view && thisArg.view.data) { - context = Object.assign({}, context, thisArg.view.data); - } - return context; - } - function initialConfig(str, pattern, options) { - if (isOptions(pattern)) { - options = pattern; - pattern = null; - } - if (isOptions(str)) { - options = str; - pattern = null; - str = null; - } - return { str, pattern, options }; - } - function setLocale(str, pattern, options) { - const config = initialConfig(str, pattern, options); - const defaults = { lang: "en", date: new Date(config.str) }; - const opts = getContext(this, defaults, {}); - dayjs.locale(opts.lang || opts.language); - } - module.exports.date = (str, pattern, options) => { - const config = initialConfig(str, pattern, options); - if (config.str == null && config.pattern == null) { - dayjs.locale("en"); - return dayjs().format("MMMM DD, YYYY"); - } - setLocale(config.str, config.pattern, config.options); - let date = dayjs(new Date(config.str)); - if (typeof config.options === "string") { - date = config.options.toLowerCase() === "utc" ? date.utc() : date.tz(config.options); - } else { - date = date.tz(dayjs.tz.guess()); - } - if (config.pattern === "") { - return date.toISOString(); - } - return date.format(config.pattern); - }; - module.exports.duration = (str, pattern, format) => { - const config = initialConfig(str, pattern); - setLocale(config.str, config.pattern); - const duration = dayjs.duration(config.str, config.pattern); - if (format && !isOptions(format)) { - return duration.format(format); - } else { - return duration.humanize(); - } - }; - } - }); - - // ../../node_modules/is-buffer/index.js - var require_is_buffer = __commonJS({ - "../../node_modules/is-buffer/index.js"(exports, module) { - module.exports = function(obj) { - return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer); - }; - function isBuffer(obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === "function" && obj.constructor.isBuffer(obj); - } - function isSlowBuffer(obj) { - return typeof obj.readFloatLE === "function" && typeof obj.slice === "function" && isBuffer(obj.slice(0, 0)); - } - } - }); - - // ../../node_modules/typeof-article/node_modules/kind-of/index.js - var require_kind_of = __commonJS({ - "../../node_modules/typeof-article/node_modules/kind-of/index.js"(exports, module) { - var isBuffer = require_is_buffer(); - var toString = Object.prototype.toString; - module.exports = function kindOf(val) { - if (typeof val === "undefined") { - return "undefined"; - } - if (val === null) { - return "null"; - } - if (val === true || val === false || val instanceof Boolean) { - return "boolean"; - } - if (typeof val === "string" || val instanceof String) { - return "string"; - } - if (typeof val === "number" || val instanceof Number) { - return "number"; - } - if (typeof val === "function" || val instanceof Function) { - return "function"; - } - if (typeof Array.isArray !== "undefined" && Array.isArray(val)) { - return "array"; - } - if (val instanceof RegExp) { - return "regexp"; - } - if (val instanceof Date) { - return "date"; - } - var type = toString.call(val); - if (type === "[object RegExp]") { - return "regexp"; - } - if (type === "[object Date]") { - return "date"; - } - if (type === "[object Arguments]") { - return "arguments"; - } - if (type === "[object Error]") { - return "error"; - } - if (isBuffer(val)) { - return "buffer"; - } - if (type === "[object Set]") { - return "set"; - } - if (type === "[object WeakSet]") { - return "weakset"; - } - if (type === "[object Map]") { - return "map"; - } - if (type === "[object WeakMap]") { - return "weakmap"; - } - if (type === "[object Symbol]") { - return "symbol"; - } - if (type === "[object Int8Array]") { - return "int8array"; - } - if (type === "[object Uint8Array]") { - return "uint8array"; - } - if (type === "[object Uint8ClampedArray]") { - return "uint8clampedarray"; - } - if (type === "[object Int16Array]") { - return "int16array"; - } - if (type === "[object Uint16Array]") { - return "uint16array"; - } - if (type === "[object Int32Array]") { - return "int32array"; - } - if (type === "[object Uint32Array]") { - return "uint32array"; - } - if (type === "[object Float32Array]") { - return "float32array"; - } - if (type === "[object Float64Array]") { - return "float64array"; - } - return "object"; - }; - } - }); - - // ../../node_modules/typeof-article/index.js - var require_typeof_article = __commonJS({ - "../../node_modules/typeof-article/index.js"(exports, module) { - "use strict"; - var typeOf = require_kind_of(); - var types = { - "arguments": "an arguments object", - "array": "an array", - "boolean": "a boolean", - "buffer": "a buffer", - "date": "a date", - "error": "an error", - "float32array": "a float32array", - "float64array": "a float64array", - "function": "a function", - "int16array": "an int16array", - "int32array": "an int32array", - "int8array": "an int8array", - "map": "a Map", - "null": "null", - "number": "a number", - "object": "an object", - "regexp": "a regular expression", - "set": "a Set", - "string": "a string", - "symbol": "a symbol", - "uint16array": "an uint16array", - "uint32array": "an uint32array", - "uint8array": "an uint8array", - "uint8clampedarray": "an uint8clampedarray", - "undefined": "undefined", - "weakmap": "a WeakMap", - "weakset": "a WeakSet" - }; - function type(val) { - return types[typeOf(val)]; - } - type.types = types; - type.typeOf = typeOf; - module.exports = type; - } - }); - - // ../../node_modules/kind-of/index.js - var require_kind_of2 = __commonJS({ - "../../node_modules/kind-of/index.js"(exports, module) { - var toString = Object.prototype.toString; - module.exports = function kindOf(val) { - if (val === void 0) - return "undefined"; - if (val === null) - return "null"; - var type = typeof val; - if (type === "boolean") - return "boolean"; - if (type === "string") - return "string"; - if (type === "number") - return "number"; - if (type === "symbol") - return "symbol"; - if (type === "function") { - return isGeneratorFn(val) ? "generatorfunction" : "function"; - } - if (isArray(val)) - return "array"; - if (isBuffer(val)) - return "buffer"; - if (isArguments(val)) - return "arguments"; - if (isDate(val)) - return "date"; - if (isError(val)) - return "error"; - if (isRegexp(val)) - return "regexp"; - switch (ctorName(val)) { - case "Symbol": - return "symbol"; - case "Promise": - return "promise"; - case "WeakMap": - return "weakmap"; - case "WeakSet": - return "weakset"; - case "Map": - return "map"; - case "Set": - return "set"; - case "Int8Array": - return "int8array"; - case "Uint8Array": - return "uint8array"; - case "Uint8ClampedArray": - return "uint8clampedarray"; - case "Int16Array": - return "int16array"; - case "Uint16Array": - return "uint16array"; - case "Int32Array": - return "int32array"; - case "Uint32Array": - return "uint32array"; - case "Float32Array": - return "float32array"; - case "Float64Array": - return "float64array"; - } - if (isGeneratorObj(val)) { - return "generator"; - } - type = toString.call(val); - switch (type) { - case "[object Object]": - return "object"; - case "[object Map Iterator]": - return "mapiterator"; - case "[object Set Iterator]": - return "setiterator"; - case "[object String Iterator]": - return "stringiterator"; - case "[object Array Iterator]": - return "arrayiterator"; - } - return type.slice(8, -1).toLowerCase().replace(/\s/g, ""); - }; - function ctorName(val) { - return typeof val.constructor === "function" ? val.constructor.name : null; - } - function isArray(val) { - if (Array.isArray) - return Array.isArray(val); - return val instanceof Array; - } - function isError(val) { - return val instanceof Error || typeof val.message === "string" && val.constructor && typeof val.constructor.stackTraceLimit === "number"; - } - function isDate(val) { - if (val instanceof Date) - return true; - return typeof val.toDateString === "function" && typeof val.getDate === "function" && typeof val.setDate === "function"; - } - function isRegexp(val) { - if (val instanceof RegExp) - return true; - return typeof val.flags === "string" && typeof val.ignoreCase === "boolean" && typeof val.multiline === "boolean" && typeof val.global === "boolean"; - } - function isGeneratorFn(name, val) { - return ctorName(name) === "GeneratorFunction"; - } - function isGeneratorObj(val) { - return typeof val.throw === "function" && typeof val.return === "function" && typeof val.next === "function"; - } - function isArguments(val) { - try { - if (typeof val.length === "number" && typeof val.callee === "function") { - return true; - } - } catch (err) { - if (err.message.indexOf("callee") !== -1) { - return true; - } - } - return false; - } - function isBuffer(val) { - if (val.constructor && typeof val.constructor.isBuffer === "function") { - return val.constructor.isBuffer(val); - } - return false; - } - } - }); - - // ../../node_modules/handlebars-utils/index.js - var require_handlebars_utils = __commonJS({ - "../../node_modules/handlebars-utils/index.js"(exports, module) { - "use strict"; - var util = __require("util"); - var type = require_typeof_article(); - var typeOf = require_kind_of2(); - var utils = exports = module.exports; - utils.extend = extend; - utils.indexOf = indexOf; - utils.escapeExpression = escapeExpression; - utils.isEmpty = isEmpty; - utils.createFrame = createFrame; - utils.blockParams = blockParams; - utils.appendContextPath = appendContextPath; - var escape = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'", - "`": "`", - "=": "=" - }; - var badChars = /[&<>"'`=]/g; - var possible = /[&<>"'`=]/; - function escapeChar(chr) { - return escape[chr]; - } - function extend(obj) { - for (var i = 1; i < arguments.length; i++) { - for (var key in arguments[i]) { - if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { - obj[key] = arguments[i][key]; - } - } - } - return obj; - } - var toString = Object.prototype.toString; - utils.toString = toString; - var isFunction = function isFunction2(value2) { - return typeof value2 === "function"; - }; - if (isFunction(/x/)) { - utils.isFunction = isFunction = function(value2) { - return typeof value2 === "function" && toString.call(value2) === "[object Function]"; - }; - } - utils.isFunction = isFunction; - var isArray = Array.isArray || function(value2) { - return value2 && typeof value2 === "object" ? toString.call(value2) === "[object Array]" : false; - }; - utils.isArray = isArray; - function indexOf(array, value2) { - for (var i = 0, len = array.length; i < len; i++) { - if (array[i] === value2) { - return i; - } - } - return -1; - } - function escapeExpression(string) { - if (typeof string !== "string") { - if (string && string.toHTML) { - return string.toHTML(); - } else if (string == null) { - return ""; - } else if (!string) { - return string + ""; - } - string = "" + string; - } - if (!possible.test(string)) { - return string; - } - return string.replace(badChars, escapeChar); - } - function createFrame(object) { - var frame = extend({}, object); - frame._parent = object; - return frame; - } - function blockParams(params, ids) { - params.path = ids; - return params; - } - function appendContextPath(contextPath, id) { - return (contextPath ? contextPath + "." : "") + id; - } - utils.expectedType = function(param, expected, actual) { - var exp = type.types[expected]; - var val = util.inspect(actual); - return "expected " + param + " to be " + exp + " but received " + type(actual) + ": " + val; - }; - utils.isBlock = function(options) { - return utils.isOptions(options) && typeof options.fn === "function" && typeof options.inverse === "function"; - }; - utils.fn = function(val, context, options) { - if (utils.isOptions(val)) { - return utils.fn("", val, options); - } - if (utils.isOptions(context)) { - return utils.fn(val, {}, context); - } - return utils.isBlock(options) ? options.fn(context) : val; - }; - utils.inverse = function(val, context, options) { - if (utils.isOptions(val)) { - return utils.identity("", val, options); - } - if (utils.isOptions(context)) { - return utils.inverse(val, {}, context); - } - return utils.isBlock(options) ? options.inverse(context) : val; - }; - utils.value = function(val, context, options) { - if (utils.isOptions(val)) { - return utils.value(null, val, options); - } - if (utils.isOptions(context)) { - return utils.value(val, {}, context); - } - if (utils.isBlock(options)) { - return !!val ? options.fn(context) : options.inverse(context); - } - return val; - }; - utils.isOptions = function(val) { - return utils.isObject(val) && utils.isObject(val.hash); - }; - utils.isUndefined = function(val) { - return val == null || utils.isOptions(val) && val.hash != null; - }; - utils.isApp = function(thisArg) { - return utils.isObject(thisArg) && utils.isObject(thisArg.options) && utils.isObject(thisArg.app); - }; - utils.options = function(thisArg, locals, options) { - if (utils.isOptions(thisArg)) { - return utils.options({}, locals, thisArg); - } - if (utils.isOptions(locals)) { - return utils.options(thisArg, options, locals); - } - options = options || {}; - if (!utils.isOptions(options)) { - locals = Object.assign({}, locals, options); - } - var opts = Object.assign({}, locals, options.hash); - if (utils.isObject(thisArg)) { - opts = Object.assign({}, thisArg.options, opts); - } - if (opts[options.name]) { - opts = Object.assign({}, opts[options.name], opts); - } - return opts; - }; - utils.context = function(thisArg, locals, options) { - if (utils.isOptions(thisArg)) { - return utils.context({}, locals, thisArg); - } - if (utils.isOptions(locals)) { - return utils.context(thisArg, options, locals); - } - var appContext = utils.isApp(thisArg) ? thisArg.context : {}; - options = options || {}; - if (!utils.isOptions(options)) { - locals = Object.assign({}, locals, options); - } - if (utils.isOptions(options) && options.hash.root === true) { - locals = Object.assign({}, options.data.root, locals); - } - var context = Object.assign({}, appContext, locals, options.hash); - if (!utils.isApp(thisArg)) { - context = Object.assign({}, thisArg, context); - } - if (utils.isApp(thisArg) && thisArg.view && thisArg.view.data) { - context = Object.assign({}, context, thisArg.view.data); - } - return context; - }; - utils.isObject = function(val) { - return typeOf(val) === "object"; - }; - function isEmpty(val) { - if (val === 0 || typeof val === "boolean") { - return false; - } - if (val == null) { - return true; - } - if (utils.isObject(val)) { - val = Object.keys(val); - } - if (!val.length) { - return true; - } - return false; - } - utils.result = function(val) { - if (typeof val === "function") { - return val.apply(this, [].slice.call(arguments, 1)); - } - return val; - }; - utils.identity = function(val) { - return val; - }; - utils.isString = function(val) { - return typeof val === "string" && val !== ""; - }; - utils.arrayify = function(val) { - return val != null ? Array.isArray(val) ? val : [val] : []; - }; - utils.tryParse = function(str) { - try { - return JSON.parse(str); - } catch (err) { - } - return {}; - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/utils/index.js - var require_utils = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/utils/index.js"(exports) { - "use strict"; - var util = require_handlebars_utils(); - exports.contains = function(val, obj, start) { - if (val == null || obj == null || isNaN(val.length)) { - return false; - } - return val.indexOf(obj, start) !== -1; - }; - exports.chop = function(str) { - if (typeof str !== "string") - return ""; - var re = /^[-_.\W\s]+|[-_.\W\s]+$/g; - return str.trim().replace(re, ""); - }; - exports.changecase = function(str, fn) { - if (typeof str !== "string") - return ""; - if (str.length === 1) { - return str.toLowerCase(); - } - str = exports.chop(str).toLowerCase(); - if (typeof fn !== "function") { - fn = util.identity; - } - var re = /[-_.\W\s]+(\w|$)/g; - return str.replace(re, function(_, ch) { - return fn(ch); - }); - }; - exports.random = function(min, max) { - return min + Math.floor(Math.random() * (max - min + 1)); - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/math.js - var require_math = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/math.js"(exports, module) { - "use strict"; - var utils = require_utils(); - var helpers2 = module.exports; - helpers2.abs = function(num) { - if (isNaN(num)) { - throw new TypeError("expected a number"); - } - return Math.abs(num); - }; - helpers2.add = function(a, b) { - if (!isNaN(a) && !isNaN(b)) { - return Number(a) + Number(b); - } - if (typeof a === "string" && typeof b === "string") { - return a + b; - } - return ""; - }; - helpers2.avg = function() { - const args = [].concat.apply([], arguments); - args.pop(); - return helpers2.sum(args) / args.length; - }; - helpers2.ceil = function(num) { - if (isNaN(num)) { - throw new TypeError("expected a number"); - } - return Math.ceil(num); - }; - helpers2.divide = function(a, b) { - if (isNaN(a)) { - throw new TypeError("expected the first argument to be a number"); - } - if (isNaN(b)) { - throw new TypeError("expected the second argument to be a number"); - } - return Number(a) / Number(b); - }; - helpers2.floor = function(num) { - if (isNaN(num)) { - throw new TypeError("expected a number"); - } - return Math.floor(num); - }; - helpers2.minus = function(a, b) { - if (isNaN(a)) { - throw new TypeError("expected the first argument to be a number"); - } - if (isNaN(b)) { - throw new TypeError("expected the second argument to be a number"); - } - return Number(a) - Number(b); - }; - helpers2.modulo = function(a, b) { - if (isNaN(a)) { - throw new TypeError("expected the first argument to be a number"); - } - if (isNaN(b)) { - throw new TypeError("expected the second argument to be a number"); - } - return Number(a) % Number(b); - }; - helpers2.multiply = function(a, b) { - if (isNaN(a)) { - throw new TypeError("expected the first argument to be a number"); - } - if (isNaN(b)) { - throw new TypeError("expected the second argument to be a number"); - } - return Number(a) * Number(b); - }; - helpers2.plus = function(a, b) { - if (isNaN(a)) { - throw new TypeError("expected the first argument to be a number"); - } - if (isNaN(b)) { - throw new TypeError("expected the second argument to be a number"); - } - return Number(a) + Number(b); - }; - helpers2.random = function(min, max) { - if (isNaN(min)) { - throw new TypeError("expected minimum to be a number"); - } - if (isNaN(max)) { - throw new TypeError("expected maximum to be a number"); - } - return utils.random(min, max); - }; - helpers2.remainder = function(a, b) { - return a % b; - }; - helpers2.round = function(num) { - if (isNaN(num)) { - throw new TypeError("expected a number"); - } - return Math.round(num); - }; - helpers2.subtract = function(a, b) { - if (isNaN(a)) { - throw new TypeError("expected the first argument to be a number"); - } - if (isNaN(b)) { - throw new TypeError("expected the second argument to be a number"); - } - return Number(a) - Number(b); - }; - helpers2.sum = function() { - var args = [].concat.apply([], arguments); - var len = args.length; - var sum = 0; - while (len--) { - if (!isNaN(args[len])) { - sum += Number(args[len]); - } - } - return sum; - }; - } - }); - - // ../../node_modules/isobject/index.js - var require_isobject = __commonJS({ - "../../node_modules/isobject/index.js"(exports, module) { - "use strict"; - module.exports = function isObject(val) { - return val != null && typeof val === "object" && Array.isArray(val) === false; - }; - } - }); - - // ../../node_modules/get-value/index.js - var require_get_value = __commonJS({ - "../../node_modules/get-value/index.js"(exports, module) { - var isObject = require_isobject(); - module.exports = function(target, path, options) { - if (!isObject(options)) { - options = { default: options }; - } - if (!isValidObject(target)) { - return typeof options.default !== "undefined" ? options.default : target; - } - if (typeof path === "number") { - path = String(path); - } - const isArray = Array.isArray(path); - const isString = typeof path === "string"; - const splitChar = options.separator || "."; - const joinChar = options.joinChar || (typeof splitChar === "string" ? splitChar : "."); - if (!isString && !isArray) { - return target; - } - if (isString && path in target) { - return isValid(path, target, options) ? target[path] : options.default; - } - let segs = isArray ? path : split(path, splitChar, options); - let len = segs.length; - let idx = 0; - do { - let prop = segs[idx]; - if (typeof prop === "number") { - prop = String(prop); - } - while (prop && prop.slice(-1) === "\\") { - prop = join([prop.slice(0, -1), segs[++idx] || ""], joinChar, options); - } - if (prop in target) { - if (!isValid(prop, target, options)) { - return options.default; - } - target = target[prop]; - } else { - let hasProp = false; - let n = idx + 1; - while (n < len) { - prop = join([prop, segs[n++]], joinChar, options); - if (hasProp = prop in target) { - if (!isValid(prop, target, options)) { - return options.default; - } - target = target[prop]; - idx = n - 1; - break; - } - } - if (!hasProp) { - return options.default; - } - } - } while (++idx < len && isValidObject(target)); - if (idx === len) { - return target; - } - return options.default; - }; - function join(segs, joinChar, options) { - if (typeof options.join === "function") { - return options.join(segs); - } - return segs[0] + joinChar + segs[1]; - } - function split(path, splitChar, options) { - if (typeof options.split === "function") { - return options.split(path); - } - return path.split(splitChar); - } - function isValid(key, target, options) { - if (typeof options.isValid === "function") { - return options.isValid(key, target); - } - return true; - } - function isValidObject(val) { - return isObject(val) || Array.isArray(val) || typeof val === "function"; - } - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/utils/createFrame.js - var require_createFrame = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/utils/createFrame.js"(exports, module) { - "use strict"; - module.exports = function createFrame(data) { - if (typeof data !== "object") { - throw new TypeError("createFrame expects data to be an object"); - } - var frame = Object.assign({}, data); - frame._parent = data; - frame.extend = function(data2) { - Object.assign(this, data2); - }; - if (arguments.length > 1) { - var args = [].slice.call(arguments, 1); - var len = args.length, i = -1; - while (++i < len) { - frame.extend(args[i] || {}); - } - } - return frame; - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/array.js - var require_array = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/array.js"(exports, module) { - "use strict"; - var util = require_handlebars_utils(); - var helpers2 = module.exports; - var getValue = require_get_value(); - var createFrame = require_createFrame(); - helpers2.after = function(array, n) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - return array.slice(n); - } - return ""; - }; - helpers2.arrayify = function(value2) { - if (util.isUndefined(value2)) - return []; - return value2 ? Array.isArray(value2) ? value2 : [value2] : []; - }; - helpers2.before = function(array, n) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - return array.slice(0, n - 1); - } - return ""; - }; - helpers2.eachIndex = function(array, options) { - var result = ""; - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - for (var i = 0; i < array.length; i++) { - result += options.fn({ item: array[i], index: i }); - } - } - return result; - }; - helpers2.filter = function(array, value2, options) { - if (util.isUndefined(array)) - return options.inverse(this); - array = util.result(array); - if (Array.isArray(array)) { - var content = ""; - var results = []; - var prop = options.hash && (options.hash.property || options.hash.prop); - if (prop) { - results = array.filter(function(val) { - return value2 === getValue(val, prop); - }); - } else { - results = array.filter(function(v) { - return value2 === v; - }); - } - if (results && results.length > 0) { - for (var i = 0; i < results.length; i++) { - content += options.fn(results[i]); - } - return content; - } - } - return options.inverse(this); - }; - helpers2.first = function(array, n) { - if (util.isUndefined(array)) - return []; - array = util.result(array); - if (Array.isArray(array)) { - if (isNaN(n)) { - return array[0]; - } - return array.slice(0, n); - } - return []; - }; - helpers2.forEach = function(array, options) { - if (util.isUndefined(array)) - return options.inverse(this); - array = util.result(array); - if (Array.isArray(array)) { - var data = createFrame(options, options.hash); - var len = array.length; - var buffer = ""; - var i = -1; - while (++i < len) { - var item = array[i]; - data.index = i; - item.index = i + 1; - item.total = len; - item.isFirst = i === 0; - item.isLast = i === len - 1; - buffer += options.fn(item, { data }); - } - return buffer; - } - return options.inverse(this); - }; - helpers2.inArray = function(array, value2, options) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - return util.value(util.indexOf(array, value2) > -1, this, options); - } - return ""; - }; - helpers2.isArray = function(value2) { - return Array.isArray(value2); - }; - helpers2.itemAt = function(array, idx) { - if (util.isUndefined(array)) - return null; - array = util.result(array); - if (Array.isArray(array)) { - idx = !isNaN(idx) ? +idx : 0; - if (idx < 0) { - return array[array.length + idx]; - } - if (idx < array.length) { - return array[idx]; - } - } - return null; - }; - helpers2.join = function(array, separator) { - if (util.isUndefined(array)) - return ""; - if (typeof array === "string") - return array; - array = util.result(array); - if (Array.isArray(array)) { - separator = util.isString(separator) ? separator : ", "; - return array.join(separator); - } - return ""; - }; - helpers2.equalsLength = function(value2, length, options) { - if (util.isOptions(length)) { - options = length; - length = 0; - } - var len = helpers2.length(value2); - return util.value(len === length, this, options); - }; - helpers2.last = function(array, n) { - if (util.isUndefined(array)) - return ""; - if (!Array.isArray(array) && typeof value !== "string") { - return ""; - } - if (isNaN(n)) { - return array[array.length - 1]; - } - return array.slice(-Math.abs(n)); - }; - helpers2.length = function(array) { - if (util.isUndefined(array)) - return 0; - if (util.isObject(array) && !util.isOptions(array)) { - array = Object.keys(array); - } - if (typeof array === "string" && array.startsWith("[") && array.endsWith("]")) { - return array.split(",").length; - } - if (typeof array === "string" || Array.isArray(array)) { - return array.length; - } - return 0; - }; - helpers2.lengthEqual = helpers2.equalsLength; - helpers2.map = function(array, iter) { - if (util.isUndefined(array)) - return ""; - if (!Array.isArray(array)) - return ""; - var len = array.length; - var res = new Array(len); - var i = -1; - if (typeof iter !== "function") { - return array; - } - while (++i < len) { - res[i] = iter(array[i], i, array); - } - return res; - }; - helpers2.pluck = function(array, prop) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - var res = []; - for (var i = 0; i < array.length; i++) { - var val = getValue(array[i], prop); - if (typeof val !== "undefined") { - res.push(val); - } - } - return res; - } - return ""; - }; - helpers2.reverse = function(array) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - array.reverse(); - return array; - } - if (array && typeof array === "string") { - return array.split("").reverse().join(""); - } - return ""; - }; - helpers2.some = function(array, iter, options) { - if (util.isUndefined(array)) - return options.inverse(this); - array = util.result(array); - if (Array.isArray(array)) { - for (var i = 0; i < array.length; i++) { - if (iter(array[i], i, array)) { - return options.fn(this); - } - } - } - return options.inverse(this); - }; - helpers2.sort = function(array, options) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - if (getValue(options, "hash.reverse")) { - return array.sort().reverse(); - } - return array.sort(); - } - return ""; - }; - helpers2.sortBy = function(array, prop, options) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - var args = [].slice.call(arguments); - args.pop(); - if (!util.isString(prop) && typeof prop !== "function") { - return array.sort(); - } - if (typeof prop === "function") { - return array.sort(prop); - } - return array.sort((a, b) => a[prop] > b[prop] ? 1 : -1); - } - return ""; - }; - helpers2.withAfter = function(array, idx, options) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - array = array.slice(idx); - var result = ""; - for (var i = 0; i < array.length; i++) { - result += options.fn(array[i]); - } - return result; - } - return ""; - }; - helpers2.withBefore = function(array, idx, options) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - array = array.slice(0, -idx); - var result = ""; - for (var i = 0; i < array.length; i++) { - result += options.fn(array[i]); - } - return result; - } - return ""; - }; - helpers2.withFirst = function(array, idx, options) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - if (!util.isUndefined(idx)) { - idx = parseFloat(util.result(idx)); - } - if (util.isUndefined(idx)) { - options = idx; - return options.fn(array[0]); - } - array = array.slice(0, idx); - var result = ""; - for (var i = 0; i < array.length; i++) { - result += options.fn(array[i]); - } - return result; - } - return ""; - }; - helpers2.withGroup = function(array, size, options) { - if (util.isUndefined(array)) - return ""; - var result = ""; - array = util.result(array); - if (Array.isArray(array) && array.length > 0) { - var subcontext = []; - for (var i = 0; i < array.length; i++) { - if (i > 0 && i % size === 0) { - result += options.fn(subcontext); - subcontext = []; - } - subcontext.push(array[i]); - } - result += options.fn(subcontext); - } - return result; - }; - helpers2.withLast = function(array, idx, options) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - if (!util.isUndefined(idx)) { - idx = parseFloat(util.result(idx)); - } - if (util.isUndefined(idx)) { - options = idx; - return options.fn(array[array.length - 1]); - } - array = array.slice(-idx); - var len = array.length, i = -1; - var result = ""; - while (++i < len) { - result += options.fn(array[i]); - } - return result; - } - return ""; - }; - helpers2.withSort = function(array, prop, options) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - var result = ""; - if (util.isUndefined(prop)) { - options = prop; - array = array.sort(); - if (getValue(options, "hash.reverse")) { - array = array.reverse(); - } - for (var i = 0, len = array.length; i < len; i++) { - result += options.fn(array[i]); - } - return result; - } - array.sort(function(a, b) { - a = getValue(a, prop); - b = getValue(b, prop); - return a > b ? 1 : a < b ? -1 : 0; - }); - if (getValue(options, "hash.reverse")) { - array = array.reverse(); - } - var alen = array.length, j = -1; - while (++j < alen) { - result += options.fn(array[j]); - } - return result; - } - return ""; - }; - helpers2.unique = function(array, options) { - if (util.isUndefined(array)) - return ""; - array = util.result(array); - if (Array.isArray(array)) { - return array.filter(function(item, index, arr) { - return arr.indexOf(item) === index; - }); - } - return ""; - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/number.js - var require_number = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/number.js"(exports, module) { - "use strict"; - var util = require_handlebars_utils(); - var helpers2 = module.exports; - helpers2.bytes = function(number, precision, options) { - if (number == null) - return "0 B"; - if (isNaN(number)) { - number = number.length; - if (!number) - return "0 B"; - } - if (isNaN(precision)) { - precision = 2; - } - var abbr = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; - precision = Math.pow(10, precision); - number = Number(number); - var len = abbr.length - 1; - while (len-- >= 0) { - var size = Math.pow(10, len * 3); - if (size <= number + 1) { - number = Math.round(number * precision / size) / precision; - number += " " + abbr[len]; - break; - } - } - return number; - }; - helpers2.addCommas = function(num) { - return num.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"); - }; - helpers2.phoneNumber = function(num) { - num = num.toString(); - return "(" + num.substr(0, 3) + ") " + num.substr(3, 3) + "-" + num.substr(6, 4); - }; - helpers2.toAbbr = function(number, precision) { - if (isNaN(number)) { - number = 0; - } - if (util.isUndefined(precision)) { - precision = 2; - } - number = Number(number); - precision = Math.pow(10, precision); - var abbr = ["k", "m", "b", "t", "q"]; - var len = abbr.length - 1; - while (len >= 0) { - var size = Math.pow(10, (len + 1) * 3); - if (size <= number + 1) { - number = Math.round(number * precision / size) / precision; - number += abbr[len]; - break; - } - len--; - } - return number; - }; - helpers2.toExponential = function(number, digits) { - if (isNaN(number)) { - number = 0; - } - if (util.isUndefined(digits)) { - digits = 0; - } - return Number(number).toExponential(digits); - }; - helpers2.toFixed = function(number, digits) { - if (isNaN(number)) { - number = 0; - } - if (isNaN(digits)) { - digits = 0; - } - return Number(number).toFixed(digits); - }; - helpers2.toFloat = function(number) { - return parseFloat(number); - }; - helpers2.toInt = function(number) { - return parseInt(number, 10); - }; - helpers2.toPrecision = function(number, precision) { - if (isNaN(number)) { - number = 0; - } - if (isNaN(precision)) { - precision = 1; - } - return Number(number).toPrecision(precision); - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/url.js - var require_url = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/url.js"(exports, module) { - "use strict"; - var url = __require("url"); - var util = require_handlebars_utils(); - var querystring = __require("querystring"); - var helpers2 = module.exports; - helpers2.encodeURI = function(str) { - if (util.isString(str)) { - return encodeURIComponent(str); - } - }; - helpers2.escape = function(str) { - if (util.isString(str)) { - return querystring.escape(str); - } - }; - helpers2.decodeURI = function(str) { - if (util.isString(str)) { - return decodeURIComponent(str); - } - }; - helpers2.urlResolve = function(base, href) { - return url.resolve(base, href); - }; - helpers2.urlParse = function(str) { - return url.parse(str); - }; - helpers2.stripQuerystring = function(str) { - if (util.isString(str)) { - return str.split("?")[0]; - } - }; - helpers2.stripProtocol = function(str) { - if (util.isString(str)) { - var parsed = url.parse(str); - parsed.protocol = ""; - return parsed.format(); - } - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/string.js - var require_string = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/string.js"(exports, module) { - "use strict"; - var util = require_handlebars_utils(); - var utils = require_utils(); - var helpers2 = module.exports; - helpers2.append = function(str, suffix) { - if (typeof str === "string" && typeof suffix === "string") { - return str + suffix; - } - return str; - }; - helpers2.camelcase = function(str) { - if (typeof str !== "string") - return ""; - return utils.changecase(str, function(ch) { - return ch.toUpperCase(); - }); - }; - helpers2.capitalize = function(str) { - if (typeof str !== "string") - return ""; - return str.charAt(0).toUpperCase() + str.slice(1); - }; - helpers2.capitalizeAll = function(str) { - if (typeof str !== "string") - return ""; - if (util.isString(str)) { - return str.replace(/\w\S*/g, function(word) { - return helpers2.capitalize(word); - }); - } - }; - helpers2.center = function(str, spaces) { - if (typeof str !== "string") - return ""; - var space = ""; - var i = 0; - while (i < spaces) { - space += " "; - i++; - } - return space + str + space; - }; - helpers2.chop = function(str) { - if (typeof str !== "string") - return ""; - return utils.chop(str); - }; - helpers2.dashcase = function(str) { - if (typeof str !== "string") - return ""; - return utils.changecase(str, function(ch) { - return "-" + ch; - }); - }; - helpers2.dotcase = function(str) { - if (typeof str !== "string") - return ""; - return utils.changecase(str, function(ch) { - return "." + ch; - }); - }; - helpers2.downcase = function() { - return helpers2.lowercase.apply(this, arguments); - }; - helpers2.ellipsis = function(str, limit) { - if (util.isString(str)) { - if (str.length <= limit) { - return str; - } - return helpers2.truncate(str, limit) + "\u2026"; - } - }; - helpers2.hyphenate = function(str) { - if (typeof str !== "string") - return ""; - return str.split(" ").join("-"); - }; - helpers2.isString = function(value2) { - return typeof value2 === "string"; - }; - helpers2.lowercase = function(str) { - if (util.isObject(str) && str.fn) { - return str.fn(this).toLowerCase(); - } - if (typeof str !== "string") - return ""; - return str.toLowerCase(); - }; - helpers2.occurrences = function(str, substring) { - if (typeof str !== "string") - return ""; - var len = substring.length; - var pos = 0; - var n = 0; - while ((pos = str.indexOf(substring, pos)) > -1) { - n++; - pos += len; - } - return n; - }; - helpers2.pascalcase = function(str) { - if (typeof str !== "string") - return ""; - str = utils.changecase(str, function(ch) { - return ch.toUpperCase(); - }); - return str.charAt(0).toUpperCase() + str.slice(1); - }; - helpers2.pathcase = function(str) { - if (typeof str !== "string") - return ""; - return utils.changecase(str, function(ch) { - return "/" + ch; - }); - }; - helpers2.plusify = function(str, ch) { - if (typeof str !== "string") - return ""; - if (!util.isString(ch)) - ch = " "; - return str.split(ch).join("+"); - }; - helpers2.prepend = function(str, prefix) { - return typeof str === "string" && typeof prefix === "string" ? prefix + str : str; - }; - helpers2.raw = function(options) { - var str = options.fn(); - var opts = util.options(this, options); - if (opts.escape !== false) { - var idx = 0; - while ((idx = str.indexOf("{{", idx)) !== -1) { - if (str[idx - 1] !== "\\") { - str = str.slice(0, idx) + "\\" + str.slice(idx); - } - idx += 3; - } - } - return str; - }; - helpers2.remove = function(str, ch) { - if (typeof str !== "string") - return ""; - if (!util.isString(ch)) - return str; - return str.split(ch).join(""); - }; - helpers2.removeFirst = function(str, ch) { - if (typeof str !== "string") - return ""; - if (!util.isString(ch)) - return str; - return str.replace(ch, ""); - }; - helpers2.replace = function(str, a, b) { - if (typeof str !== "string") - return ""; - if (!util.isString(a)) - return str; - if (!util.isString(b)) - b = ""; - return str.split(a).join(b); - }; - helpers2.replaceFirst = function(str, a, b) { - if (typeof str !== "string") - return ""; - if (!util.isString(a)) - return str; - if (!util.isString(b)) - b = ""; - return str.replace(a, b); - }; - helpers2.reverse = require_array().reverse; - helpers2.sentence = function(str) { - if (typeof str !== "string") - return ""; - return str.replace(/((?:\S[^\.\?\!]*)[\.\?\!]*)/g, function(txt) { - return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); - }); - }; - helpers2.snakecase = function(str) { - if (typeof str !== "string") - return ""; - return utils.changecase(str, function(ch) { - return "_" + ch; - }); - }; - helpers2.split = function(str, ch) { - if (typeof str !== "string") - return ""; - if (!util.isString(ch)) - ch = ","; - return str.split(ch); - }; - helpers2.startsWith = function(prefix, str, options) { - var args = [].slice.call(arguments); - options = args.pop(); - if (util.isString(str) && str.indexOf(prefix) === 0) { - return options.fn(this); - } - if (typeof options.inverse === "function") { - return options.inverse(this); - } - return ""; - }; - helpers2.titleize = function(str) { - if (typeof str !== "string") - return ""; - var title = str.replace(/[- _]+/g, " "); - var words = title.split(" "); - var len = words.length; - var res = []; - var i = 0; - while (len--) { - var word = words[i++]; - res.push(exports.capitalize(word)); - } - return res.join(" "); - }; - helpers2.trim = function(str) { - return typeof str === "string" ? str.trim() : ""; - }; - helpers2.trimLeft = function(str) { - if (util.isString(str)) { - return str.replace(/^\s+/, ""); - } - }; - helpers2.trimRight = function(str) { - if (util.isString(str)) { - return str.replace(/\s+$/, ""); - } - }; - helpers2.truncate = function(str, limit, suffix) { - if (util.isString(str)) { - if (typeof suffix !== "string") { - suffix = ""; - } - if (str.length > limit) { - return str.slice(0, limit - suffix.length) + suffix; - } - return str; - } - }; - helpers2.truncateWords = function(str, count, suffix) { - if (util.isString(str) && !isNaN(count)) { - if (typeof suffix !== "string") { - suffix = "\u2026"; - } - var num = Number(count); - var arr = str.split(/[ \t]/); - if (num >= arr.length) { - return str; - } - arr = arr.slice(0, num); - var val = arr.join(" ").trim(); - return val + suffix; - } - }; - helpers2.upcase = function() { - return helpers2.uppercase.apply(this, arguments); - }; - helpers2.uppercase = function(str) { - if (util.isObject(str) && str.fn) { - return str.fn(this).toUpperCase(); - } - if (typeof str !== "string") - return ""; - return str.toUpperCase(); - }; - } - }); - - // ../../node_modules/has-values/index.js - var require_has_values = __commonJS({ - "../../node_modules/has-values/index.js"(exports, module) { - "use strict"; - var typeOf = require_kind_of2(); - module.exports = function has(val) { - switch (typeOf(val)) { - case "boolean": - case "date": - case "function": - case "null": - case "number": - return true; - case "undefined": - return false; - case "regexp": - return val.source !== "(?:)" && val.source !== ""; - case "buffer": - return val.toString() !== ""; - case "error": - return val.message !== ""; - case "string": - case "arguments": - return val.length !== 0; - case "file": - case "map": - case "set": - return val.size !== 0; - case "array": - case "object": - for (const key of Object.keys(val)) { - if (has(val[key])) { - return true; - } - } - return false; - default: { - return true; - } - } - }; - } - }); - - // ../../node_modules/has-value/index.js - var require_has_value = __commonJS({ - "../../node_modules/has-value/index.js"(exports, module) { - "use strict"; - var get = require_get_value(); - var has = require_has_values(); - module.exports = function(obj, path, options) { - if (isObject(obj) && (typeof path === "string" || Array.isArray(path))) { - return has(get(obj, path, options)); - } - return false; - }; - function isObject(val) { - return val != null && (typeof val === "object" || typeof val === "function" || Array.isArray(val)); - } - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/utils/falsey.js - var require_falsey = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/utils/falsey.js"(exports, module) { - "use strict"; - function falsey(val, keywords) { - if (!val) - return true; - let words = keywords || falsey.keywords; - if (!Array.isArray(words)) - words = [words]; - const lower = typeof val === "string" ? val.toLowerCase() : null; - for (const word of words) { - if (word === val) { - return true; - } - if (word === lower) { - return true; - } - } - return false; - } - falsey.keywords = [ - "0", - "false", - "nada", - "nil", - "nay", - "nah", - "negative", - "no", - "none", - "nope", - "nul", - "null", - "nix", - "nyet", - "uh-uh", - "veto", - "zero" - ]; - module.exports = falsey; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/utils/odd.js - var require_odd = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/utils/odd.js"(exports, module) { - "use strict"; - module.exports = function isOdd(value2) { - const n = Math.abs(value2); - if (isNaN(n)) { - throw new TypeError("expected a number"); - } - if (!Number.isInteger(n)) { - throw new Error("expected an integer"); - } - if (!Number.isSafeInteger(n)) { - throw new Error("value exceeds maximum safe integer"); - } - return n % 2 === 1; - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/comparison.js - var require_comparison = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/comparison.js"(exports, module) { - "use strict"; - var has = require_has_value(); - var util = require_handlebars_utils(); - var utils = require_utils(); - var falsey = require_falsey(); - var isOdd = require_odd(); - var helpers2 = module.exports; - helpers2.and = function() { - var len = arguments.length - 1; - var options = arguments[len]; - var val = true; - for (var i = 0; i < len; i++) { - if (!arguments[i]) { - val = false; - break; - } - } - return util.value(val, this, options); - }; - helpers2.compare = function(a, operator, b, options) { - if (arguments.length < 4) { - throw new Error("handlebars Helper {{compare}} expects 4 arguments"); - } - var result; - switch (operator) { - case "==": - result = a == b; - break; - case "===": - result = a === b; - break; - case "!=": - result = a != b; - break; - case "!==": - result = a !== b; - break; - case "<": - result = a < b; - break; - case ">": - result = a > b; - break; - case "<=": - result = a <= b; - break; - case ">=": - result = a >= b; - break; - case "typeof": - result = typeof a === b; - break; - default: { - throw new Error( - "helper {{compare}}: invalid operator: `" + operator + "`" - ); - } - } - return util.value(result, this, options); - }; - helpers2.contains = function(collection, value2, startIndex, options) { - if (typeof startIndex === "object") { - options = startIndex; - startIndex = void 0; - } - var val = utils.contains(collection, value2, startIndex); - return util.value(val, this, options); - }; - helpers2.default = function() { - for (var i = 0; i < arguments.length - 1; i++) { - if (arguments[i] != null) - return arguments[i]; - } - return ""; - }; - helpers2.eq = function(a, b, options) { - if (arguments.length === 2) { - options = b; - b = options.hash.compare; - } - return util.value(a === b, this, options); - }; - helpers2.gt = function(a, b, options) { - if (arguments.length === 2) { - options = b; - b = options.hash.compare; - } - return util.value(a > b, this, options); - }; - helpers2.gte = function(a, b, options) { - if (arguments.length === 2) { - options = b; - b = options.hash.compare; - } - return util.value(a >= b, this, options); - }; - helpers2.has = function(value2, pattern, options) { - if (util.isOptions(value2)) { - options = value2; - pattern = null; - value2 = null; - } - if (util.isOptions(pattern)) { - options = pattern; - pattern = null; - } - if (value2 === null) { - return util.value(false, this, options); - } - if (arguments.length === 2) { - return util.value(has(this, value2), this, options); - } - if ((Array.isArray(value2) || util.isString(value2)) && util.isString(pattern)) { - if (value2.indexOf(pattern) > -1) { - return util.fn(true, this, options); - } - } - if (util.isObject(value2) && util.isString(pattern) && pattern in value2) { - return util.fn(true, this, options); - } - return util.inverse(false, this, options); - }; - helpers2.isFalsey = function(val, options) { - return util.value(falsey(val), this, options); - }; - helpers2.isTruthy = function(val, options) { - return util.value(!falsey(val), this, options); - }; - helpers2.ifEven = function(num, options) { - return util.value(!isOdd(num), this, options); - }; - helpers2.ifNth = function(a, b, options) { - var isNth = !isNaN(a) && !isNaN(b) && b % a === 0; - return util.value(isNth, this, options); - }; - helpers2.ifOdd = function(val, options) { - return util.value(isOdd(val), this, options); - }; - helpers2.is = function(a, b, options) { - if (arguments.length === 2) { - options = b; - b = options.hash.compare; - } - return util.value(a == b, this, options); - }; - helpers2.isnt = function(a, b, options) { - if (arguments.length === 2) { - options = b; - b = options.hash.compare; - } - return util.value(a != b, this, options); - }; - helpers2.lt = function(a, b, options) { - if (arguments.length === 2) { - options = b; - b = options.hash.compare; - } - return util.value(a < b, this, options); - }; - helpers2.lte = function(a, b, options) { - if (arguments.length === 2) { - options = b; - b = options.hash.compare; - } - return util.value(a <= b, this, options); - }; - helpers2.neither = function(a, b, options) { - return util.value(!a && !b, this, options); - }; - helpers2.not = function(val, options) { - return util.value(!val, this, options); - }; - helpers2.or = function() { - var len = arguments.length - 1; - var options = arguments[len]; - var val = false; - for (var i = 0; i < len; i++) { - if (arguments[i]) { - val = true; - break; - } - } - return util.value(val, this, options); - }; - helpers2.unlessEq = function(a, b, options) { - if (util.isOptions(b)) { - options = b; - b = options.hash.compare; - } - return util.value(a !== b, this, options); - }; - helpers2.unlessGt = function(a, b, options) { - if (util.isOptions(b)) { - options = b; - b = options.hash.compare; - } - return util.value(a <= b, this, options); - }; - helpers2.unlessLt = function(a, b, options) { - if (util.isOptions(b)) { - options = b; - b = options.hash.compare; - } - return util.value(a >= b, this, options); - }; - helpers2.unlessGteq = function(a, b, options) { - if (util.isOptions(b)) { - options = b; - b = options.hash.compare; - } - return util.value(a < b, this, options); - }; - helpers2.unlessLteq = function(a, b, options) { - if (util.isOptions(b)) { - options = b; - b = options.hash.compare; - } - return util.value(a > b, this, options); - }; - } - }); - - // ../../node_modules/is-number/node_modules/kind-of/index.js - var require_kind_of3 = __commonJS({ - "../../node_modules/is-number/node_modules/kind-of/index.js"(exports, module) { - var isBuffer = require_is_buffer(); - var toString = Object.prototype.toString; - module.exports = function kindOf(val) { - if (typeof val === "undefined") { - return "undefined"; - } - if (val === null) { - return "null"; - } - if (val === true || val === false || val instanceof Boolean) { - return "boolean"; - } - if (typeof val === "string" || val instanceof String) { - return "string"; - } - if (typeof val === "number" || val instanceof Number) { - return "number"; - } - if (typeof val === "function" || val instanceof Function) { - return "function"; - } - if (typeof Array.isArray !== "undefined" && Array.isArray(val)) { - return "array"; - } - if (val instanceof RegExp) { - return "regexp"; - } - if (val instanceof Date) { - return "date"; - } - var type = toString.call(val); - if (type === "[object RegExp]") { - return "regexp"; - } - if (type === "[object Date]") { - return "date"; - } - if (type === "[object Arguments]") { - return "arguments"; - } - if (type === "[object Error]") { - return "error"; - } - if (isBuffer(val)) { - return "buffer"; - } - if (type === "[object Set]") { - return "set"; - } - if (type === "[object WeakSet]") { - return "weakset"; - } - if (type === "[object Map]") { - return "map"; - } - if (type === "[object WeakMap]") { - return "weakmap"; - } - if (type === "[object Symbol]") { - return "symbol"; - } - if (type === "[object Int8Array]") { - return "int8array"; - } - if (type === "[object Uint8Array]") { - return "uint8array"; - } - if (type === "[object Uint8ClampedArray]") { - return "uint8clampedarray"; - } - if (type === "[object Int16Array]") { - return "int16array"; - } - if (type === "[object Uint16Array]") { - return "uint16array"; - } - if (type === "[object Int32Array]") { - return "int32array"; - } - if (type === "[object Uint32Array]") { - return "uint32array"; - } - if (type === "[object Float32Array]") { - return "float32array"; - } - if (type === "[object Float64Array]") { - return "float64array"; - } - return "object"; - }; - } - }); - - // ../../node_modules/is-number/index.js - var require_is_number = __commonJS({ - "../../node_modules/is-number/index.js"(exports, module) { - "use strict"; - var typeOf = require_kind_of3(); - module.exports = function isNumber(num) { - var type = typeOf(num); - if (type !== "number" && type !== "string") { - return false; - } - var n = +num; - return n - n + 1 >= 0 && num !== ""; - }; - } - }); - - // ../../node_modules/get-object/index.js - var require_get_object = __commonJS({ - "../../node_modules/get-object/index.js"(exports, module) { - "use strict"; - var isNumber = require_is_number(); - module.exports = function getObject(obj, prop) { - if (!prop) - return obj; - if (!obj) - return {}; - var segs = String(prop).split(/[[.\]]/).filter(Boolean); - var last = segs[segs.length - 1], res = {}; - while (prop = segs.shift()) { - obj = obj[prop]; - if (!obj) - return {}; - } - if (isNumber(last)) - return [obj]; - res[last] = obj; - return res; - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/object.js - var require_object = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/object.js"(exports, module) { - "use strict"; - var hasOwn = Object.hasOwnProperty; - var util = require_handlebars_utils(); - var array = require_array(); - var helpers2 = module.exports; - var getValue = require_get_value(); - var getObject = require_get_object(); - var createFrame = require_createFrame(); - helpers2.extend = function() { - var args = [].slice.call(arguments); - var opts = {}; - if (util.isOptions(args[args.length - 1])) { - opts = args.pop().hash; - args.push(opts); - } - var context = {}; - for (var i = 0; i < args.length; i++) { - var obj = args[i]; - if (util.isObject(obj)) { - var keys = Object.keys(obj); - for (var j = 0; j < keys.length; j++) { - var key = keys[j]; - context[key] = obj[key]; - } - } - } - return context; - }; - helpers2.forIn = function(obj, options) { - if (!util.isOptions(options)) { - return obj.inverse(this); - } - var data = createFrame(options, options.hash); - var result = ""; - for (var key in obj) { - data.key = key; - result += options.fn(obj[key], { data }); - } - return result; - }; - helpers2.forOwn = function(obj, options) { - if (!util.isOptions(options)) { - return obj.inverse(this); - } - var data = createFrame(options, options.hash); - var result = ""; - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - data.key = key; - result += options.fn(obj[key], { data }); - } - } - return result; - }; - helpers2.toPath = function() { - var prop = []; - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] === "string" || typeof arguments[i] === "number") { - prop.push(arguments[i]); - } - } - return prop.join("."); - }; - helpers2.get = function(prop, context, options) { - var val = getValue(context, prop); - if (options && options.fn) { - return val ? options.fn(val) : options.inverse(context); - } - return val; - }; - helpers2.getObject = function(prop, context) { - return getObject(context, prop); - }; - helpers2.hasOwn = function(context, key) { - return hasOwn.call(context, key); - }; - helpers2.isObject = function(value2) { - return typeof value2 === "object"; - }; - helpers2.JSONparse = function(str, options) { - return JSON.parse(str); - }; - helpers2.JSONstringify = function(obj, indent) { - if (isNaN(indent)) { - indent = 0; - } - return JSON.stringify(obj, null, indent); - }; - helpers2.merge = function(context) { - var args = [].slice.call(arguments); - var opts = {}; - if (util.isOptions(args[args.length - 1])) { - opts = args.pop().hash; - args.push(opts); - } - return Object.assign.apply(null, args); - }; - helpers2.parseJSON = helpers2.JSONparse; - helpers2.pick = function(props, context, options) { - var keys = array.arrayify(props); - var len = keys.length, i = -1; - var result = {}; - while (++i < len) { - result = helpers2.extend({}, result, getObject(context, keys[i])); - } - if (options.fn) { - if (Object.keys(result).length) { - return options.fn(result); - } - return options.inverse(context); - } - return result; - }; - helpers2.stringify = helpers2.JSONstringify; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/regex.js - var require_regex = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/regex.js"(exports, module) { - "use strict"; - var util = require_handlebars_utils(); - var helpers2 = module.exports; - var kindOf = require_kind_of2(); - helpers2.toRegex = function(str, locals, options) { - var opts = util.options({}, locals, options); - return new RegExp(str, opts.flags); - }; - helpers2.test = function(str, regex) { - if (typeof str !== "string") { - return false; - } - if (kindOf(regex) !== "regexp") { - throw new TypeError("expected a regular expression"); - } - return regex.test(str); - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/rng.js - function rng() { - if (poolPtr > rnds8Pool.length - 16) { - import_crypto.default.randomFillSync(rnds8Pool); - poolPtr = 0; - } - return rnds8Pool.slice(poolPtr, poolPtr += 16); - } - var import_crypto, rnds8Pool, poolPtr; - var init_rng = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/rng.js"() { - import_crypto = __toESM(__require("crypto")); - rnds8Pool = new Uint8Array(256); - poolPtr = rnds8Pool.length; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/regex.js - var regex_default; - var init_regex = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/regex.js"() { - regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/validate.js - function validate(uuid) { - return typeof uuid === "string" && regex_default.test(uuid); - } - var validate_default; - var init_validate = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/validate.js"() { - init_regex(); - validate_default = validate; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/stringify.js - function unsafeStringify(arr, offset = 0) { - return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; - } - function stringify(arr, offset = 0) { - const uuid = unsafeStringify(arr, offset); - if (!validate_default(uuid)) { - throw TypeError("Stringified UUID is invalid"); - } - return uuid; - } - var byteToHex, stringify_default; - var init_stringify = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/stringify.js"() { - init_validate(); - byteToHex = []; - for (let i = 0; i < 256; ++i) { - byteToHex.push((i + 256).toString(16).slice(1)); - } - stringify_default = stringify; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v1.js - function v1(options, buf, offset) { - let i = buf && offset || 0; - const b = buf || new Array(16); - options = options || {}; - let node = options.node || _nodeId; - let clockseq = options.clockseq !== void 0 ? options.clockseq : _clockseq; - if (node == null || clockseq == null) { - const seedBytes = options.random || (options.rng || rng)(); - if (node == null) { - node = _nodeId = [seedBytes[0] | 1, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; - } - if (clockseq == null) { - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 16383; - } - } - let msecs = options.msecs !== void 0 ? options.msecs : Date.now(); - let nsecs = options.nsecs !== void 0 ? options.nsecs : _lastNSecs + 1; - const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 1e4; - if (dt < 0 && options.clockseq === void 0) { - clockseq = clockseq + 1 & 16383; - } - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === void 0) { - nsecs = 0; - } - if (nsecs >= 1e4) { - throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); - } - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - msecs += 122192928e5; - const tl = ((msecs & 268435455) * 1e4 + nsecs) % 4294967296; - b[i++] = tl >>> 24 & 255; - b[i++] = tl >>> 16 & 255; - b[i++] = tl >>> 8 & 255; - b[i++] = tl & 255; - const tmh = msecs / 4294967296 * 1e4 & 268435455; - b[i++] = tmh >>> 8 & 255; - b[i++] = tmh & 255; - b[i++] = tmh >>> 24 & 15 | 16; - b[i++] = tmh >>> 16 & 255; - b[i++] = clockseq >>> 8 | 128; - b[i++] = clockseq & 255; - for (let n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - return buf || unsafeStringify(b); - } - var _nodeId, _clockseq, _lastMSecs, _lastNSecs, v1_default; - var init_v1 = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v1.js"() { - init_rng(); - init_stringify(); - _lastMSecs = 0; - _lastNSecs = 0; - v1_default = v1; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/parse.js - function parse(uuid) { - if (!validate_default(uuid)) { - throw TypeError("Invalid UUID"); - } - let v; - const arr = new Uint8Array(16); - arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; - arr[1] = v >>> 16 & 255; - arr[2] = v >>> 8 & 255; - arr[3] = v & 255; - arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; - arr[5] = v & 255; - arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; - arr[7] = v & 255; - arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; - arr[9] = v & 255; - arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255; - arr[11] = v / 4294967296 & 255; - arr[12] = v >>> 24 & 255; - arr[13] = v >>> 16 & 255; - arr[14] = v >>> 8 & 255; - arr[15] = v & 255; - return arr; - } - var parse_default; - var init_parse = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/parse.js"() { - init_validate(); - parse_default = parse; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v35.js - function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); - const bytes = []; - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); - } - return bytes; - } - function v35(name, version2, hashfunc) { - function generateUUID(value2, namespace, buf, offset) { - var _namespace; - if (typeof value2 === "string") { - value2 = stringToBytes(value2); - } - if (typeof namespace === "string") { - namespace = parse_default(namespace); - } - if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { - throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)"); - } - let bytes = new Uint8Array(16 + value2.length); - bytes.set(namespace); - bytes.set(value2, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 15 | version2; - bytes[8] = bytes[8] & 63 | 128; - if (buf) { - offset = offset || 0; - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - return buf; - } - return unsafeStringify(bytes); - } - try { - generateUUID.name = name; - } catch (err) { - } - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; - } - var DNS, URL; - var init_v35 = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v35.js"() { - init_stringify(); - init_parse(); - DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; - URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/md5.js - function md5(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === "string") { - bytes = Buffer.from(bytes, "utf8"); - } - return import_crypto2.default.createHash("md5").update(bytes).digest(); - } - var import_crypto2, md5_default; - var init_md5 = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/md5.js"() { - import_crypto2 = __toESM(__require("crypto")); - md5_default = md5; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v3.js - var v3, v3_default; - var init_v3 = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v3.js"() { - init_v35(); - init_md5(); - v3 = v35("v3", 48, md5_default); - v3_default = v3; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/native.js - var import_crypto3, native_default; - var init_native = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/native.js"() { - import_crypto3 = __toESM(__require("crypto")); - native_default = { - randomUUID: import_crypto3.default.randomUUID - }; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v4.js - function v4(options, buf, offset) { - if (native_default.randomUUID && !buf && !options) { - return native_default.randomUUID(); - } - options = options || {}; - const rnds = options.random || (options.rng || rng)(); - rnds[6] = rnds[6] & 15 | 64; - rnds[8] = rnds[8] & 63 | 128; - if (buf) { - offset = offset || 0; - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; - } - return buf; - } - return unsafeStringify(rnds); - } - var v4_default; - var init_v4 = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v4.js"() { - init_native(); - init_rng(); - init_stringify(); - v4_default = v4; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/sha1.js - function sha1(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === "string") { - bytes = Buffer.from(bytes, "utf8"); - } - return import_crypto4.default.createHash("sha1").update(bytes).digest(); - } - var import_crypto4, sha1_default; - var init_sha1 = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/sha1.js"() { - import_crypto4 = __toESM(__require("crypto")); - sha1_default = sha1; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v5.js - var v5, v5_default; - var init_v5 = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/v5.js"() { - init_v35(); - init_sha1(); - v5 = v35("v5", 80, sha1_default); - v5_default = v5; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/nil.js - var nil_default; - var init_nil = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/nil.js"() { - nil_default = "00000000-0000-0000-0000-000000000000"; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/version.js - function version(uuid) { - if (!validate_default(uuid)) { - throw TypeError("Invalid UUID"); - } - return parseInt(uuid.slice(14, 15), 16); - } - var version_default; - var init_version = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/version.js"() { - init_validate(); - version_default = version; - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/index.js - var esm_node_exports = {}; - __export(esm_node_exports, { - NIL: () => nil_default, - parse: () => parse_default, - stringify: () => stringify_default, - v1: () => v1_default, - v3: () => v3_default, - v4: () => v4_default, - v5: () => v5_default, - validate: () => validate_default, - version: () => version_default - }); - var init_esm_node = __esm({ - "../../node_modules/@budibase/handlebars-helpers/node_modules/uuid/dist/esm-node/index.js"() { - init_v1(); - init_v3(); - init_v4(); - init_v5(); - init_nil(); - init_version(); - init_validate(); - init_stringify(); - init_parse(); - } - }); - - // ../../node_modules/@budibase/handlebars-helpers/lib/uuid.js - var require_uuid = __commonJS({ - "../../node_modules/@budibase/handlebars-helpers/lib/uuid.js"(exports, module) { - var uuid = (init_esm_node(), __toCommonJS(esm_node_exports)); - var helpers2 = module.exports; - helpers2.uuid = function() { - return uuid.v4(); - }; - } - }); - - // ../string-templates/src/helpers/list.js - var require_list = __commonJS({ - "../string-templates/src/helpers/list.js"(exports, module) { - var { date, duration } = require_date(); - var externalCollections = { - math: require_math(), - array: require_array(), - number: require_number(), - url: require_url(), - string: require_string(), - comparison: require_comparison(), - object: require_object(), - regex: require_regex(), - uuid: require_uuid() - }; - var helpersToRemoveForJs = ["sortBy"]; - module.exports.helpersToRemoveForJs = helpersToRemoveForJs; - var addedHelpers = { - date, - duration - }; - var helpers2 = void 0; - module.exports.getJsHelperList = () => { - if (helpers2) { - return helpers2; - } - helpers2 = {}; - for (let collection of Object.values(externalCollections)) { - for (let [key, func] of Object.entries(collection)) { - helpers2[key] = (...props) => func(...props, {}); - } - } - for (let key of Object.keys(addedHelpers)) { - helpers2[key] = addedHelpers[key]; - } - for (const toRemove of helpersToRemoveForJs) { - delete helpers2[toRemove]; - } - Object.freeze(helpers2); - return helpers2; - }; - } - }); - - // src/jsRunner/bundles/index-helpers.ts - var index_helpers_exports = {}; - __export(index_helpers_exports, { - helpers: () => helpers - }); - var { - getJsHelperList - } = require_list(); - var helpers = { - ...getJsHelperList(), - // pointing stripProtocol to a unexisting function to be able to declare it on isolated-vm - // @ts-ignore - // eslint-disable-next-line no-undef - stripProtocol: helpersStripProtocol - }; - return __toCommonJS(index_helpers_exports); -})(); +"use strict";var helpers=(()=>{var hn=Object.create;var Se=Object.defineProperty;var pn=Object.getOwnPropertyDescriptor;var mn=Object.getOwnPropertyNames;var gn=Object.getPrototypeOf,yn=Object.prototype.hasOwnProperty;var fe=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Z=(e,t)=>()=>(e&&(t=e(e=0)),t);var U=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),yt=(e,t)=>{for(var r in t)Se(e,r,{get:t[r],enumerable:!0})},vt=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of mn(t))!yn.call(e,i)&&i!==r&&Se(e,i,{get:()=>t[i],enumerable:!(n=pn(t,i))||n.enumerable});return e};var Ne=(e,t,r)=>(r=e!=null?hn(gn(e)):{},vt(t||!e||!e.__esModule?Se(r,"default",{value:e,enumerable:!0}):r,e)),$t=e=>vt(Se({},"__esModule",{value:!0}),e);var bt=U((qe,Ye)=>{(function(e,t){typeof qe=="object"&&typeof Ye<"u"?Ye.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs=t()})(qe,function(){"use strict";var e=1e3,t=6e4,r=36e5,n="millisecond",i="second",u="minute",s="hour",f="day",w="week",g="month",l="quarter",x="year",v="date",a="Invalid Date",T=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,E=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,I={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function($){var h=["th","st","nd","rd"],c=$%100;return"["+$+(h[(c-20)%10]||h[c]||h[0])+"]"}},Y=function($,h,c){var b=String($);return!b||b.length>=h?$:""+Array(h+1-b.length).join(c)+$},F={s:Y,z:function($){var h=-$.utcOffset(),c=Math.abs(h),b=Math.floor(c/60),d=c%60;return(h<=0?"+":"-")+Y(b,2,"0")+":"+Y(d,2,"0")},m:function $(h,c){if(h.date()1)return $(j[0])}else{var _=h.name;S[_]=h,d=_}return!b&&d&&(q=d),d||!b&&q},N=function($,h){if(o($))return $.clone();var c=typeof h=="object"?h:{};return c.date=$,c.args=arguments,new B(c)},O=F;O.l=D,O.i=o,O.w=function($,h){return N($,{locale:h.$L,utc:h.$u,x:h.$x,$offset:h.$offset})};var B=function(){function $(c){this.$L=D(c.locale,null,!0),this.parse(c),this.$x=this.$x||c.x||{},this[p]=!0}var h=$.prototype;return h.parse=function(c){this.$d=function(b){var d=b.date,M=b.utc;if(d===null)return new Date(NaN);if(O.u(d))return new Date;if(d instanceof Date)return new Date(d);if(typeof d=="string"&&!/Z$/i.test(d)){var j=d.match(T);if(j){var _=j[2]-1||0,H=(j[7]||"0").substring(0,3);return M?new Date(Date.UTC(j[1],_,j[3]||1,j[4]||0,j[5]||0,j[6]||0,H)):new Date(j[1],_,j[3]||1,j[4]||0,j[5]||0,j[6]||0,H)}}return new Date(d)}(c),this.init()},h.init=function(){var c=this.$d;this.$y=c.getFullYear(),this.$M=c.getMonth(),this.$D=c.getDate(),this.$W=c.getDay(),this.$H=c.getHours(),this.$m=c.getMinutes(),this.$s=c.getSeconds(),this.$ms=c.getMilliseconds()},h.$utils=function(){return O},h.isValid=function(){return this.$d.toString()!==a},h.isSame=function(c,b){var d=N(c);return this.startOf(b)<=d&&d<=this.endOf(b)},h.isAfter=function(c,b){return N(c){(function(e,t){typeof Ce=="object"&&typeof Ee<"u"?Ee.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_duration=t()})(Ce,function(){"use strict";var e,t,r=1e3,n=6e4,i=36e5,u=864e5,s=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,f=31536e6,w=2628e6,g=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/,l={years:f,months:w,days:u,hours:i,minutes:n,seconds:r,milliseconds:1,weeks:6048e5},x=function(S){return S instanceof F},v=function(S,p,o){return new F(S,o,p.$l)},a=function(S){return t.p(S)+"s"},T=function(S){return S<0},E=function(S){return T(S)?Math.ceil(S):Math.floor(S)},I=function(S){return Math.abs(S)},Y=function(S,p){return S?T(S)?{negative:!0,format:""+I(S)+p}:{negative:!1,format:""+S+p}:{negative:!1,format:""}},F=function(){function S(o,D,N){var O=this;if(this.$d={},this.$l=N,o===void 0&&(this.$ms=0,this.parseFromMilliseconds()),D)return v(o*l[a(D)],this);if(typeof o=="number")return this.$ms=o,this.parseFromMilliseconds(),this;if(typeof o=="object")return Object.keys(o).forEach(function($){O.$d[a($)]=o[$]}),this.calMilliseconds(),this;if(typeof o=="string"){var B=o.match(g);if(B){var J=B.slice(2).map(function($){return $!=null?Number($):0});return this.$d.years=J[0],this.$d.months=J[1],this.$d.weeks=J[2],this.$d.days=J[3],this.$d.hours=J[4],this.$d.minutes=J[5],this.$d.seconds=J[6],this.calMilliseconds(),this}}return this}var p=S.prototype;return p.calMilliseconds=function(){var o=this;this.$ms=Object.keys(this.$d).reduce(function(D,N){return D+(o.$d[N]||0)*l[N]},0)},p.parseFromMilliseconds=function(){var o=this.$ms;this.$d.years=E(o/f),o%=f,this.$d.months=E(o/w),o%=w,this.$d.days=E(o/u),o%=u,this.$d.hours=E(o/i),o%=i,this.$d.minutes=E(o/n),o%=n,this.$d.seconds=E(o/r),o%=r,this.$d.milliseconds=o},p.toISOString=function(){var o=Y(this.$d.years,"Y"),D=Y(this.$d.months,"M"),N=+this.$d.days||0;this.$d.weeks&&(N+=7*this.$d.weeks);var O=Y(N,"D"),B=Y(this.$d.hours,"H"),J=Y(this.$d.minutes,"M"),$=this.$d.seconds||0;this.$d.milliseconds&&($+=this.$d.milliseconds/1e3,$=Math.round(1e3*$)/1e3);var h=Y($,"S"),c=o.negative||D.negative||O.negative||B.negative||J.negative||h.negative,b=B.format||J.format||h.format?"T":"",d=(c?"-":"")+"P"+o.format+D.format+O.format+b+B.format+J.format+h.format;return d==="P"||d==="-P"?"P0D":d},p.toJSON=function(){return this.toISOString()},p.format=function(o){var D=o||"YYYY-MM-DDTHH:mm:ss",N={Y:this.$d.years,YY:t.s(this.$d.years,2,"0"),YYYY:t.s(this.$d.years,4,"0"),M:this.$d.months,MM:t.s(this.$d.months,2,"0"),D:this.$d.days,DD:t.s(this.$d.days,2,"0"),H:this.$d.hours,HH:t.s(this.$d.hours,2,"0"),m:this.$d.minutes,mm:t.s(this.$d.minutes,2,"0"),s:this.$d.seconds,ss:t.s(this.$d.seconds,2,"0"),SSS:t.s(this.$d.milliseconds,3,"0")};return D.replace(s,function(O,B){return B||String(N[O])})},p.as=function(o){return this.$ms/l[a(o)]},p.get=function(o){var D=this.$ms,N=a(o);return N==="milliseconds"?D%=1e3:D=N==="weeks"?E(D/l[N]):this.$d[N],D||0},p.add=function(o,D,N){var O;return O=D?o*l[a(D)]:x(o)?o.$ms:v(o,this).$ms,v(this.$ms+O*(N?-1:1),this)},p.subtract=function(o,D){return this.add(o,D,!0)},p.locale=function(o){var D=this.clone();return D.$l=o,D},p.clone=function(){return v(this.$ms,this)},p.humanize=function(o){return e().add(this.$ms,"ms").locale(this.$l).fromNow(!o)},p.valueOf=function(){return this.asMilliseconds()},p.milliseconds=function(){return this.get("milliseconds")},p.asMilliseconds=function(){return this.as("milliseconds")},p.seconds=function(){return this.get("seconds")},p.asSeconds=function(){return this.as("seconds")},p.minutes=function(){return this.get("minutes")},p.asMinutes=function(){return this.as("minutes")},p.hours=function(){return this.get("hours")},p.asHours=function(){return this.as("hours")},p.days=function(){return this.get("days")},p.asDays=function(){return this.as("days")},p.weeks=function(){return this.get("weeks")},p.asWeeks=function(){return this.as("weeks")},p.months=function(){return this.get("months")},p.asMonths=function(){return this.as("months")},p.years=function(){return this.get("years")},p.asYears=function(){return this.as("years")},S}(),q=function(S,p,o){return S.add(p.years()*o,"y").add(p.months()*o,"M").add(p.days()*o,"d").add(p.hours()*o,"h").add(p.minutes()*o,"m").add(p.seconds()*o,"s").add(p.milliseconds()*o,"ms")};return function(S,p,o){e=o,t=o().$utils(),o.duration=function(O,B){var J=o.locale();return v(O,{$l:J},B)},o.isDuration=x;var D=p.prototype.add,N=p.prototype.subtract;p.prototype.add=function(O,B){return x(O)?q(this,O,1):D.bind(this)(O,B)},p.prototype.subtract=function(O,B){return x(O)?q(this,O,-1):N.bind(this)(O,B)}}})});var Ot=U((Ie,_e)=>{(function(e,t){typeof Ie=="object"&&typeof _e<"u"?_e.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_advancedFormat=t()})(Ie,function(){"use strict";return function(e,t){var r=t.prototype,n=r.format;r.format=function(i){var u=this,s=this.$locale();if(!this.isValid())return n.bind(this)(i);var f=this.$utils(),w=(i||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(g){switch(g){case"Q":return Math.ceil((u.$M+1)/3);case"Do":return s.ordinal(u.$D);case"gggg":return u.weekYear();case"GGGG":return u.isoWeekYear();case"wo":return s.ordinal(u.week(),"W");case"w":case"ww":return f.s(u.week(),g==="w"?1:2,"0");case"W":case"WW":return f.s(u.isoWeek(),g==="W"?1:2,"0");case"k":case"kk":return f.s(String(u.$H===0?24:u.$H),g==="k"?1:2,"0");case"X":return Math.floor(u.$d.getTime()/1e3);case"x":return u.$d.getTime();case"z":return"["+u.offsetName()+"]";case"zzz":return"["+u.offsetName("long")+"]";default:return g}});return n.bind(this)(w)}}})});var xt=U((We,Fe)=>{(function(e,t){typeof We=="object"&&typeof Fe<"u"?Fe.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_isoWeek=t()})(We,function(){"use strict";var e="day";return function(t,r,n){var i=function(f){return f.add(4-f.isoWeekday(),e)},u=r.prototype;u.isoWeekYear=function(){return i(this).year()},u.isoWeek=function(f){if(!this.$utils().u(f))return this.add(7*(f-this.isoWeek()),e);var w,g,l,x,v=i(this),a=(w=this.isoWeekYear(),g=this.$u,l=(g?n.utc:n)().year(w).startOf("year"),x=4-l.isoWeekday(),l.isoWeekday()>4&&(x+=7),l.add(x,e));return v.diff(a,"week")+1},u.isoWeekday=function(f){return this.$utils().u(f)?this.day()||7:this.day(this.day()%7?f:f-7)};var s=u.startOf;u.startOf=function(f,w){var g=this.$utils(),l=!!g.u(w)||w;return g.p(f)==="isoweek"?l?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):s.bind(this)(f,w)}}})});var St=U((He,Be)=>{(function(e,t){typeof He=="object"&&typeof Be<"u"?Be.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_weekYear=t()})(He,function(){"use strict";return function(e,t){t.prototype.weekYear=function(){var r=this.month(),n=this.week(),i=this.year();return n===1&&r===11?i+1:r===0&&n>=52?i-1:i}}})});var Nt=U((Le,ze)=>{(function(e,t){typeof Le=="object"&&typeof ze<"u"?ze.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_weekOfYear=t()})(Le,function(){"use strict";var e="week",t="year";return function(r,n,i){var u=n.prototype;u.week=function(s){if(s===void 0&&(s=null),s!==null)return this.add(7*(s-this.week()),"day");var f=this.$locale().yearStart||1;if(this.month()===11&&this.date()>25){var w=i(this).startOf(t).add(1,t).date(f),g=i(this).endOf(e);if(w.isBefore(g))return 1}var l=i(this).startOf(t).date(f).startOf(e).subtract(1,"millisecond"),x=this.diff(l,e,!0);return x<0?i(this).startOf("week").week():Math.ceil(x)},u.weeks=function(s){return s===void 0&&(s=null),this.week(s)}}})});var Mt=U((Pe,Re)=>{(function(e,t){typeof Pe=="object"&&typeof Re<"u"?Re.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_relativeTime=t()})(Pe,function(){"use strict";return function(e,t,r){e=e||{};var n=t.prototype,i={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function u(f,w,g,l){return n.fromToBase(f,w,g,l)}r.en.relativeTime=i,n.fromToBase=function(f,w,g,l,x){for(var v,a,T,E=g.$locale().relativeTime||i,I=e.thresholds||[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],Y=I.length,F=0;F0,S<=q.r||!q.r){S<=1&&F>0&&(q=I[F-1]);var p=E[q.l];x&&(S=x(""+S)),a=typeof p=="string"?p.replace("%d",S):p(S,w,q.l,T);break}}if(w)return a;var o=T?E.future:E.past;return typeof o=="function"?o(a):o.replace("%s",a)},n.to=function(f,w){return u(f,w,this,!0)},n.from=function(f,w){return u(f,w,this)};var s=function(f){return f.$u?r.utc():r()};n.toNow=function(f){return this.to(s(this),f)},n.fromNow=function(f){return this.from(s(this),f)}}})});var jt=U((Je,Ge)=>{(function(e,t){typeof Je=="object"&&typeof Ge<"u"?Ge.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_utc=t()})(Je,function(){"use strict";var e="minute",t=/[+-]\d\d(?::?\d\d)?/g,r=/([+-]|\d\d)/g;return function(n,i,u){var s=i.prototype;u.utc=function(a){var T={date:a,utc:!0,args:arguments};return new i(T)},s.utc=function(a){var T=u(this.toDate(),{locale:this.$L,utc:!0});return a?T.add(this.utcOffset(),e):T},s.local=function(){return u(this.toDate(),{locale:this.$L,utc:!1})};var f=s.parse;s.parse=function(a){a.utc&&(this.$u=!0),this.$utils().u(a.$offset)||(this.$offset=a.$offset),f.call(this,a)};var w=s.init;s.init=function(){if(this.$u){var a=this.$d;this.$y=a.getUTCFullYear(),this.$M=a.getUTCMonth(),this.$D=a.getUTCDate(),this.$W=a.getUTCDay(),this.$H=a.getUTCHours(),this.$m=a.getUTCMinutes(),this.$s=a.getUTCSeconds(),this.$ms=a.getUTCMilliseconds()}else w.call(this)};var g=s.utcOffset;s.utcOffset=function(a,T){var E=this.$utils().u;if(E(a))return this.$u?0:E(this.$offset)?g.call(this):this.$offset;if(typeof a=="string"&&(a=function(q){q===void 0&&(q="");var S=q.match(t);if(!S)return null;var p=(""+S[0]).match(r)||["-",0,0],o=p[0],D=60*+p[1]+ +p[2];return D===0?0:o==="+"?D:-D}(a),a===null))return this;var I=Math.abs(a)<=16?60*a:a,Y=this;if(T)return Y.$offset=I,Y.$u=a===0,Y;if(a!==0){var F=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();(Y=this.local().add(I+F,e)).$offset=I,Y.$x.$localOffset=F}else Y=this.utc();return Y};var l=s.format;s.format=function(a){var T=a||(this.$u?"YYYY-MM-DDTHH:mm:ss[Z]":"");return l.call(this,T)},s.valueOf=function(){var a=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*a},s.isUTC=function(){return!!this.$u},s.toISOString=function(){return this.toDate().toISOString()},s.toString=function(){return this.toDate().toUTCString()};var x=s.toDate;s.toDate=function(a){return a==="s"&&this.$offset?u(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate():x.call(this)};var v=s.diff;s.diff=function(a,T,E){if(a&&this.$u===a.$u)return v.call(this,a,T,E);var I=this.local(),Y=u(a).local();return v.call(I,Y,T,E)}}})});var At=U((Ze,Ve)=>{(function(e,t){typeof Ze=="object"&&typeof Ve<"u"?Ve.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_timezone=t()})(Ze,function(){"use strict";var e={year:0,month:1,day:2,hour:3,minute:4,second:5},t={};return function(r,n,i){var u,s=function(l,x,v){v===void 0&&(v={});var a=new Date(l),T=function(E,I){I===void 0&&(I={});var Y=I.timeZoneName||"short",F=E+"|"+Y,q=t[F];return q||(q=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:E,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:Y}),t[F]=q),q}(x,v);return T.formatToParts(a)},f=function(l,x){for(var v=s(l,x),a=[],T=0;T=0&&(a[F]=parseInt(Y,10))}var q=a[3],S=q===24?0:q,p=a[0]+"-"+a[1]+"-"+a[2]+" "+S+":"+a[4]+":"+a[5]+":000",o=+l;return(i.utc(p).valueOf()-(o-=o%1e3))/6e4},w=n.prototype;w.tz=function(l,x){l===void 0&&(l=u);var v=this.utcOffset(),a=this.toDate(),T=a.toLocaleString("en-US",{timeZone:l}),E=Math.round((a-new Date(T))/1e3/60),I=i(T,{locale:this.$L}).$set("millisecond",this.$ms).utcOffset(15*-Math.round(a.getTimezoneOffset()/15)-E,!0);if(x){var Y=I.utcOffset();I=I.add(v-Y,"minute")}return I.$x.$timezone=l,I},w.offsetName=function(l){var x=this.$x.$timezone||i.tz.guess(),v=s(this.valueOf(),x,{timeZoneName:l}).find(function(a){return a.type.toLowerCase()==="timezonename"});return v&&v.value};var g=w.startOf;w.startOf=function(l,x){if(!this.$x||!this.$x.$timezone)return g.call(this,l,x);var v=i(this.format("YYYY-MM-DD HH:mm:ss:SSS"),{locale:this.$L});return g.call(v,l,x).tz(this.$x.$timezone,!0)},i.tz=function(l,x,v){var a=v&&x,T=v||x||u,E=f(+i(),T);if(typeof l!="string")return i(l).tz(T);var I=function(S,p,o){var D=S-60*p*1e3,N=f(D,o);if(p===N)return[D,p];var O=f(D-=60*(N-p)*1e3,o);return N===O?[D,N]:[S-60*Math.min(N,O)*1e3,Math.max(N,O)]}(i.utc(l,a).valueOf(),E,T),Y=I[0],F=I[1],q=i(Y).utcOffset(F);return q.$x.$timezone=T,q},i.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},i.tz.setDefault=function(l){u=l}}})});var Dt=U((Ui,et)=>{var X=bt();X.extend(wt());X.extend(Ot());X.extend(xt());X.extend(St());X.extend(Nt());X.extend(Mt());X.extend(jt());X.extend(At());function oe(e){return typeof e=="object"&&typeof e.hash=="object"}function Qe(e){return typeof e=="object"&&typeof e.options=="object"&&typeof e.app=="object"}function Xe(e,t,r){if(oe(e))return Xe({},t,e);if(oe(t))return Xe(e,r,t);let n=Qe(e)?e.context:{};r=r||{},oe(r)||(t=Object.assign({},t,r)),oe(r)&&r.hash.root===!0&&(t=Object.assign({},r.data.root,t));let i=Object.assign({},n,t,r.hash);return Qe(e)||(i=Object.assign({},e,i)),Qe(e)&&e.view&&e.view.data&&(i=Object.assign({},i,e.view.data)),i}function Ke(e,t,r){return oe(t)&&(r=t,t=null),oe(e)&&(r=e,t=null,e=null),{str:e,pattern:t,options:r}}function kt(e,t,r){let n=Ke(e,t,r),i={lang:"en",date:new Date(n.str)},u=Xe(this,i,{});X.locale(u.lang||u.language)}et.exports.date=(e,t,r)=>{let n=Ke(e,t,r);if(n.str==null&&n.pattern==null)return X.locale("en"),X().format("MMMM DD, YYYY");kt(n.str,n.pattern,n.options);let i=X(new Date(n.str));return typeof n.options=="string"?i=n.options.toLowerCase()==="utc"?i.utc():i.tz(n.options):i=i.tz(X.tz.guess()),n.pattern===""?i.toISOString():i.format(n.pattern)};et.exports.duration=(e,t,r)=>{let n=Ke(e,t);kt(n.str,n.pattern);let i=X.duration(n.str,n.pattern);return r&&!oe(r)?i.format(r):i.humanize()}});var tt=U((Ti,Tt)=>{Tt.exports=function(e){return e!=null&&(Ut(e)||vn(e)||!!e._isBuffer)};function Ut(e){return!!e.constructor&&typeof e.constructor.isBuffer=="function"&&e.constructor.isBuffer(e)}function vn(e){return typeof e.readFloatLE=="function"&&typeof e.slice=="function"&&Ut(e.slice(0,0))}});var Yt=U((qi,qt)=>{var $n=tt(),bn=Object.prototype.toString;qt.exports=function(t){if(typeof t>"u")return"undefined";if(t===null)return"null";if(t===!0||t===!1||t instanceof Boolean)return"boolean";if(typeof t=="string"||t instanceof String)return"string";if(typeof t=="number"||t instanceof Number)return"number";if(typeof t=="function"||t instanceof Function)return"function";if(typeof Array.isArray<"u"&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var r=bn.call(t);return r==="[object RegExp]"?"regexp":r==="[object Date]"?"date":r==="[object Arguments]"?"arguments":r==="[object Error]"?"error":$n(t)?"buffer":r==="[object Set]"?"set":r==="[object WeakSet]"?"weakset":r==="[object Map]"?"map":r==="[object WeakMap]"?"weakmap":r==="[object Symbol]"?"symbol":r==="[object Int8Array]"?"int8array":r==="[object Uint8Array]"?"uint8array":r==="[object Uint8ClampedArray]"?"uint8clampedarray":r==="[object Int16Array]"?"int16array":r==="[object Uint16Array]"?"uint16array":r==="[object Int32Array]"?"int32array":r==="[object Uint32Array]"?"uint32array":r==="[object Float32Array]"?"float32array":r==="[object Float64Array]"?"float64array":"object"}});var _t=U((Yi,It)=>{"use strict";var Ct=Yt(),Et={arguments:"an arguments object",array:"an array",boolean:"a boolean",buffer:"a buffer",date:"a date",error:"an error",float32array:"a float32array",float64array:"a float64array",function:"a function",int16array:"an int16array",int32array:"an int32array",int8array:"an int8array",map:"a Map",null:"null",number:"a number",object:"an object",regexp:"a regular expression",set:"a Set",string:"a string",symbol:"a symbol",uint16array:"an uint16array",uint32array:"an uint32array",uint8array:"an uint8array",uint8clampedarray:"an uint8clampedarray",undefined:"undefined",weakmap:"a WeakMap",weakset:"a WeakSet"};function rt(e){return Et[Ct(e)]}rt.types=Et;rt.typeOf=Ct;It.exports=rt});var Me=U((Ci,Ft)=>{var wn=Object.prototype.toString;Ft.exports=function(t){if(t===void 0)return"undefined";if(t===null)return"null";var r=typeof t;if(r==="boolean")return"boolean";if(r==="string")return"string";if(r==="number")return"number";if(r==="symbol")return"symbol";if(r==="function")return Mn(t)?"generatorfunction":"function";if(On(t))return"array";if(kn(t))return"buffer";if(An(t))return"arguments";if(Sn(t))return"date";if(xn(t))return"error";if(Nn(t))return"regexp";switch(Wt(t)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(jn(t))return"generator";switch(r=wn.call(t),r){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return r.slice(8,-1).toLowerCase().replace(/\s/g,"")};function Wt(e){return typeof e.constructor=="function"?e.constructor.name:null}function On(e){return Array.isArray?Array.isArray(e):e instanceof Array}function xn(e){return e instanceof Error||typeof e.message=="string"&&e.constructor&&typeof e.constructor.stackTraceLimit=="number"}function Sn(e){return e instanceof Date?!0:typeof e.toDateString=="function"&&typeof e.getDate=="function"&&typeof e.setDate=="function"}function Nn(e){return e instanceof RegExp?!0:typeof e.flags=="string"&&typeof e.ignoreCase=="boolean"&&typeof e.multiline=="boolean"&&typeof e.global=="boolean"}function Mn(e,t){return Wt(e)==="GeneratorFunction"}function jn(e){return typeof e.throw=="function"&&typeof e.return=="function"&&typeof e.next=="function"}function An(e){try{if(typeof e.length=="number"&&typeof e.callee=="function")return!0}catch(t){if(t.message.indexOf("callee")!==-1)return!0}return!1}function kn(e){return e.constructor&&typeof e.constructor.isBuffer=="function"?e.constructor.isBuffer(e):!1}});var ee=U((Lt,zt)=>{"use strict";var Dn=fe("util"),Ht=_t(),Un=Me(),m=Lt=zt.exports;m.extend=Bt;m.indexOf=In;m.escapeExpression=_n;m.isEmpty=Bn;m.createFrame=Wn;m.blockParams=Fn;m.appendContextPath=Hn;var Tn={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`","=":"="},qn=/[&<>"'`=]/g,Yn=/[&<>"'`=]/;function Cn(e){return Tn[e]}function Bt(e){for(var t=1;t{"use strict";var Ln=ee();pe.contains=function(e,t,r){return e==null||t==null||isNaN(e.length)?!1:e.indexOf(t,r)!==-1};pe.chop=function(e){if(typeof e!="string")return"";var t=/^[-_.\W\s]+|[-_.\W\s]+$/g;return e.trim().replace(t,"")};pe.changecase=function(e,t){if(typeof e!="string")return"";if(e.length===1)return e.toLowerCase();e=pe.chop(e).toLowerCase(),typeof t!="function"&&(t=Ln.identity);var r=/[-_.\W\s]+(\w|$)/g;return e.replace(r,function(n,i){return t(i)})};pe.random=function(e,t){return e+Math.floor(Math.random()*(t-e+1))}});var Rt=U((Ii,Pt)=>{"use strict";var zn=je(),V=Pt.exports;V.abs=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.abs(e)};V.add=function(e,t){return!isNaN(e)&&!isNaN(t)?Number(e)+Number(t):typeof e=="string"&&typeof t=="string"?e+t:""};V.avg=function(){let e=[].concat.apply([],arguments);return e.pop(),V.sum(e)/e.length};V.ceil=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.ceil(e)};V.divide=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)/Number(t)};V.floor=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.floor(e)};V.minus=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)-Number(t)};V.modulo=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)%Number(t)};V.multiply=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)*Number(t)};V.plus=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)+Number(t)};V.random=function(e,t){if(isNaN(e))throw new TypeError("expected minimum to be a number");if(isNaN(t))throw new TypeError("expected maximum to be a number");return zn.random(e,t)};V.remainder=function(e,t){return e%t};V.round=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.round(e)};V.subtract=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)-Number(t)};V.sum=function(){for(var e=[].concat.apply([],arguments),t=e.length,r=0;t--;)isNaN(e[t])||(r+=Number(e[t]));return r}});var Gt=U((_i,Jt)=>{"use strict";Jt.exports=function(t){return t!=null&&typeof t=="object"&&Array.isArray(t)===!1}});var Ae=U((Wi,Xt)=>{var Qt=Gt();Xt.exports=function(e,t,r){if(Qt(r)||(r={default:r}),!Vt(e))return typeof r.default<"u"?r.default:e;typeof t=="number"&&(t=String(t));let n=Array.isArray(t),i=typeof t=="string",u=r.separator||".",s=r.joinChar||(typeof u=="string"?u:".");if(!i&&!n)return e;if(i&&t in e)return ut(t,e,r)?e[t]:r.default;let f=n?t:Pn(t,u,r),w=f.length,g=0;do{let l=f[g];for(typeof l=="number"&&(l=String(l));l&&l.slice(-1)==="\\";)l=Zt([l.slice(0,-1),f[++g]||""],s,r);if(l in e){if(!ut(l,e,r))return r.default;e=e[l]}else{let x=!1,v=g+1;for(;v{"use strict";Kt.exports=function(t){if(typeof t!="object")throw new TypeError("createFrame expects data to be an object");var r=Object.assign({},t);if(r._parent=t,r.extend=function(s){Object.assign(this,s)},arguments.length>1)for(var n=[].slice.call(arguments,1),i=n.length,u=-1;++u{"use strict";var y=ee(),C=er.exports,ae=Ae(),Rn=st();C.after=function(e,t){return y.isUndefined(e)?"":(e=y.result(e),Array.isArray(e)?e.slice(t):"")};C.arrayify=function(e){return y.isUndefined(e)?[]:e?Array.isArray(e)?e:[e]:[]};C.before=function(e,t){return y.isUndefined(e)?"":(e=y.result(e),Array.isArray(e)?e.slice(0,t-1):"")};C.eachIndex=function(e,t){var r="";if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e))for(var n=0;n0){for(var s=0;s-1,this,r):"")};C.isArray=function(e){return Array.isArray(e)};C.itemAt=function(e,t){if(y.isUndefined(e))return null;if(e=y.result(e),Array.isArray(e)){if(t=isNaN(t)?0:+t,t<0)return e[e.length+t];if(ti[t]>u[t]?1:-1)}return""};C.withAfter=function(e,t,r){if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e)){e=e.slice(t);for(var n="",i=0;i0){for(var i=[],u=0;u0&&u%t===0&&(n+=r.fn(i),i=[]),i.push(e[u]);n+=r.fn(i)}return n};C.withLast=function(e,t,r){if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e)){if(y.isUndefined(t)||(t=parseFloat(y.result(t))),y.isUndefined(t))return r=t,r.fn(e[e.length-1]);e=e.slice(-t);for(var n=e.length,i=-1,u="";++ig?1:w{"use strict";var tr=ee(),te=rr.exports;te.bytes=function(e,t,r){if(e==null||isNaN(e)&&(e=e.length,!e))return"0 B";isNaN(t)&&(t=2);var n=["B","kB","MB","GB","TB","PB","EB","ZB","YB"];t=Math.pow(10,t),e=Number(e);for(var i=n.length-1;i-->=0;){var u=Math.pow(10,i*3);if(u<=e+1){e=Math.round(e*t/u)/t,e+=" "+n[i];break}}return e};te.addCommas=function(e){return e.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,")};te.phoneNumber=function(e){return e=e.toString(),"("+e.substr(0,3)+") "+e.substr(3,3)+"-"+e.substr(6,4)};te.toAbbr=function(e,t){isNaN(e)&&(e=0),tr.isUndefined(t)&&(t=2),e=Number(e),t=Math.pow(10,t);for(var r=["k","m","b","t","q"],n=r.length-1;n>=0;){var i=Math.pow(10,(n+1)*3);if(i<=e+1){e=Math.round(e*t/i)/t,e+=r[n];break}n--}return e};te.toExponential=function(e,t){return isNaN(e)&&(e=0),tr.isUndefined(t)&&(t=0),Number(e).toExponential(t)};te.toFixed=function(e,t){return isNaN(e)&&(e=0),isNaN(t)&&(t=0),Number(e).toFixed(t)};te.toFloat=function(e){return parseFloat(e)};te.toInt=function(e){return parseInt(e,10)};te.toPrecision=function(e,t){return isNaN(e)&&(e=0),isNaN(t)&&(t=1),Number(e).toPrecision(t)}});var ur=U((Li,ir)=>{"use strict";var ft=fe("url"),ye=ee(),Jn=fe("querystring"),ce=ir.exports;ce.encodeURI=function(e){if(ye.isString(e))return encodeURIComponent(e)};ce.escape=function(e){if(ye.isString(e))return Jn.escape(e)};ce.decodeURI=function(e){if(ye.isString(e))return decodeURIComponent(e)};ce.urlResolve=function(e,t){return ft.resolve(e,t)};ce.urlParse=function(e){return ft.parse(e)};ce.stripQuerystring=function(e){if(ye.isString(e))return e.split("?")[0]};ce.stripProtocol=function(e){if(ye.isString(e)){var t=ft.parse(e);return t.protocol="",t.format()}}});var or=U((sr,fr)=>{"use strict";var z=ee(),le=je(),A=fr.exports;A.append=function(e,t){return typeof e=="string"&&typeof t=="string"?e+t:e};A.camelcase=function(e){return typeof e!="string"?"":le.changecase(e,function(t){return t.toUpperCase()})};A.capitalize=function(e){return typeof e!="string"?"":e.charAt(0).toUpperCase()+e.slice(1)};A.capitalizeAll=function(e){if(typeof e!="string")return"";if(z.isString(e))return e.replace(/\w\S*/g,function(t){return A.capitalize(t)})};A.center=function(e,t){if(typeof e!="string")return"";for(var r="",n=0;n-1;)i++,n+=r;return i};A.pascalcase=function(e){return typeof e!="string"?"":(e=le.changecase(e,function(t){return t.toUpperCase()}),e.charAt(0).toUpperCase()+e.slice(1))};A.pathcase=function(e){return typeof e!="string"?"":le.changecase(e,function(t){return"/"+t})};A.plusify=function(e,t){return typeof e!="string"?"":(z.isString(t)||(t=" "),e.split(t).join("+"))};A.prepend=function(e,t){return typeof e=="string"&&typeof t=="string"?t+e:e};A.raw=function(e){var t=e.fn(),r=z.options(this,e);if(r.escape!==!1)for(var n=0;(n=t.indexOf("{{",n))!==-1;)t[n-1]!=="\\"&&(t=t.slice(0,n)+"\\"+t.slice(n)),n+=3;return t};A.remove=function(e,t){return typeof e!="string"?"":z.isString(t)?e.split(t).join(""):e};A.removeFirst=function(e,t){return typeof e!="string"?"":z.isString(t)?e.replace(t,""):e};A.replace=function(e,t,r){return typeof e!="string"?"":z.isString(t)?(z.isString(r)||(r=""),e.split(t).join(r)):e};A.replaceFirst=function(e,t,r){return typeof e!="string"?"":z.isString(t)?(z.isString(r)||(r=""),e.replace(t,r)):e};A.reverse=ke().reverse;A.sentence=function(e){return typeof e!="string"?"":e.replace(/((?:\S[^\.\?\!]*)[\.\?\!]*)/g,function(t){return t.charAt(0).toUpperCase()+t.substr(1).toLowerCase()})};A.snakecase=function(e){return typeof e!="string"?"":le.changecase(e,function(t){return"_"+t})};A.split=function(e,t){return typeof e!="string"?"":(z.isString(t)||(t=","),e.split(t))};A.startsWith=function(e,t,r){var n=[].slice.call(arguments);return r=n.pop(),z.isString(t)&&t.indexOf(e)===0?r.fn(this):typeof r.inverse=="function"?r.inverse(this):""};A.titleize=function(e){if(typeof e!="string")return"";for(var t=e.replace(/[- _]+/g," "),r=t.split(" "),n=r.length,i=[],u=0;n--;){var s=r[u++];i.push(sr.capitalize(s))}return i.join(" ")};A.trim=function(e){return typeof e=="string"?e.trim():""};A.trimLeft=function(e){if(z.isString(e))return e.replace(/^\s+/,"")};A.trimRight=function(e){if(z.isString(e))return e.replace(/\s+$/,"")};A.truncate=function(e,t,r){if(z.isString(e))return typeof r!="string"&&(r=""),e.length>t?e.slice(0,t-r.length)+r:e};A.truncateWords=function(e,t,r){if(z.isString(e)&&!isNaN(t)){typeof r!="string"&&(r="\u2026");var n=Number(t),i=e.split(/[ \t]/);if(n>=i.length)return e;i=i.slice(0,n);var u=i.join(" ").trim();return u+r}};A.upcase=function(){return A.uppercase.apply(this,arguments)};A.uppercase=function(e){return z.isObject(e)&&e.fn?e.fn(this).toUpperCase():typeof e!="string"?"":e.toUpperCase()}});var cr=U((zi,ar)=>{"use strict";var Gn=Me();ar.exports=function e(t){switch(Gn(t)){case"boolean":case"date":case"function":case"null":case"number":return!0;case"undefined":return!1;case"regexp":return t.source!=="(?:)"&&t.source!=="";case"buffer":return t.toString()!=="";case"error":return t.message!=="";case"string":case"arguments":return t.length!==0;case"file":case"map":case"set":return t.size!==0;case"array":case"object":for(let r of Object.keys(t))if(e(t[r]))return!0;return!1;default:return!0}}});var dr=U((Pi,lr)=>{"use strict";var Zn=Ae(),Vn=cr();lr.exports=function(e,t,r){return Qn(e)&&(typeof t=="string"||Array.isArray(t))?Vn(Zn(e,t,r)):!1};function Qn(e){return e!=null&&(typeof e=="object"||typeof e=="function"||Array.isArray(e))}});var pr=U((Ri,hr)=>{"use strict";function ot(e,t){if(!e)return!0;let r=t||ot.keywords;Array.isArray(r)||(r=[r]);let n=typeof e=="string"?e.toLowerCase():null;for(let i of r)if(i===e||i===n)return!0;return!1}ot.keywords=["0","false","nada","nil","nay","nah","negative","no","none","nope","nul","null","nix","nyet","uh-uh","veto","zero"];hr.exports=ot});var gr=U((Ji,mr)=>{"use strict";mr.exports=function(t){let r=Math.abs(t);if(isNaN(r))throw new TypeError("expected a number");if(!Number.isInteger(r))throw new Error("expected an integer");if(!Number.isSafeInteger(r))throw new Error("value exceeds maximum safe integer");return r%2===1}});var br=U((Gi,$r)=>{"use strict";var Xn=dr(),k=ee(),Kn=je(),yr=pr(),vr=gr(),W=$r.exports;W.and=function(){for(var e=arguments.length-1,t=arguments[e],r=!0,n=0;n":i=e>r;break;case"<=":i=e<=r;break;case">=":i=e>=r;break;case"typeof":i=typeof e===r;break;default:throw new Error("helper {{compare}}: invalid operator: `"+t+"`")}return k.value(i,this,n)};W.contains=function(e,t,r,n){typeof r=="object"&&(n=r,r=void 0);var i=Kn.contains(e,t,r);return k.value(i,this,n)};W.default=function(){for(var e=0;et,this,r)};W.gte=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e>=t,this,r)};W.has=function(e,t,r){return k.isOptions(e)&&(r=e,t=null,e=null),k.isOptions(t)&&(r=t,t=null),e===null?k.value(!1,this,r):arguments.length===2?k.value(Xn(this,e),this,r):(Array.isArray(e)||k.isString(e))&&k.isString(t)&&e.indexOf(t)>-1?k.fn(!0,this,r):k.isObject(e)&&k.isString(t)&&t in e?k.fn(!0,this,r):k.inverse(!1,this,r)};W.isFalsey=function(e,t){return k.value(yr(e),this,t)};W.isTruthy=function(e,t){return k.value(!yr(e),this,t)};W.ifEven=function(e,t){return k.value(!vr(e),this,t)};W.ifNth=function(e,t,r){var n=!isNaN(e)&&!isNaN(t)&&t%e===0;return k.value(n,this,r)};W.ifOdd=function(e,t){return k.value(vr(e),this,t)};W.is=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e==t,this,r)};W.isnt=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e!=t,this,r)};W.lt=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e=t,this,r)};W.unlessGteq=function(e,t,r){return k.isOptions(t)&&(r=t,t=r.hash.compare),k.value(et,this,r)}});var Or=U((Zi,wr)=>{var ei=tt(),ti=Object.prototype.toString;wr.exports=function(t){if(typeof t>"u")return"undefined";if(t===null)return"null";if(t===!0||t===!1||t instanceof Boolean)return"boolean";if(typeof t=="string"||t instanceof String)return"string";if(typeof t=="number"||t instanceof Number)return"number";if(typeof t=="function"||t instanceof Function)return"function";if(typeof Array.isArray<"u"&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var r=ti.call(t);return r==="[object RegExp]"?"regexp":r==="[object Date]"?"date":r==="[object Arguments]"?"arguments":r==="[object Error]"?"error":ei(t)?"buffer":r==="[object Set]"?"set":r==="[object WeakSet]"?"weakset":r==="[object Map]"?"map":r==="[object WeakMap]"?"weakmap":r==="[object Symbol]"?"symbol":r==="[object Int8Array]"?"int8array":r==="[object Uint8Array]"?"uint8array":r==="[object Uint8ClampedArray]"?"uint8clampedarray":r==="[object Int16Array]"?"int16array":r==="[object Uint16Array]"?"uint16array":r==="[object Int32Array]"?"int32array":r==="[object Uint32Array]"?"uint32array":r==="[object Float32Array]"?"float32array":r==="[object Float64Array]"?"float64array":"object"}});var Sr=U((Vi,xr)=>{"use strict";var ri=Or();xr.exports=function(t){var r=ri(t);if(r!=="number"&&r!=="string")return!1;var n=+t;return n-n+1>=0&&t!==""}});var Mr=U((Qi,Nr)=>{"use strict";var ni=Sr();Nr.exports=function(t,r){if(!r)return t;if(!t)return{};for(var n=String(r).split(/[[.\]]/).filter(Boolean),i=n[n.length-1],u={};r=n.shift();)if(t=t[r],!t)return{};return ni(i)?[t]:(u[i]=t,u)}});var Dr=U((Xi,kr)=>{"use strict";var ii=Object.hasOwnProperty,ve=ee(),ui=ke(),P=kr.exports,si=Ae(),jr=Mr(),Ar=st();P.extend=function(){var e=[].slice.call(arguments),t={};ve.isOptions(e[e.length-1])&&(t=e.pop().hash,e.push(t));for(var r={},n=0;n{"use strict";var fi=ee(),Ur=Tr.exports,oi=Me();Ur.toRegex=function(e,t,r){var n=fi.options({},t,r);return new RegExp(e,n.flags)};Ur.test=function(e,t){if(typeof e!="string")return!1;if(oi(t)!=="regexp")throw new TypeError("expected a regular expression");return t.test(e)}});function $e(){return De>Ue.length-16&&(Yr.default.randomFillSync(Ue),De=0),Ue.slice(De,De+=16)}var Yr,Ue,De,at=Z(()=>{Yr=Ne(fe("crypto")),Ue=new Uint8Array(256),De=Ue.length});var Cr,Er=Z(()=>{Cr=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i});function ai(e){return typeof e=="string"&&Cr.test(e)}var ne,be=Z(()=>{Er();ne=ai});function de(e,t=0){return R[e[t+0]]+R[e[t+1]]+R[e[t+2]]+R[e[t+3]]+"-"+R[e[t+4]]+R[e[t+5]]+"-"+R[e[t+6]]+R[e[t+7]]+"-"+R[e[t+8]]+R[e[t+9]]+"-"+R[e[t+10]]+R[e[t+11]]+R[e[t+12]]+R[e[t+13]]+R[e[t+14]]+R[e[t+15]]}function ci(e,t=0){let r=de(e,t);if(!ne(r))throw TypeError("Stringified UUID is invalid");return r}var R,Ir,we=Z(()=>{be();R=[];for(let e=0;e<256;++e)R.push((e+256).toString(16).slice(1));Ir=ci});function li(e,t,r){let n=t&&r||0,i=t||new Array(16);e=e||{};let u=e.node||_r,s=e.clockseq!==void 0?e.clockseq:ct;if(u==null||s==null){let v=e.random||(e.rng||$e)();u==null&&(u=_r=[v[0]|1,v[1],v[2],v[3],v[4],v[5]]),s==null&&(s=ct=(v[6]<<8|v[7])&16383)}let f=e.msecs!==void 0?e.msecs:Date.now(),w=e.nsecs!==void 0?e.nsecs:dt+1,g=f-lt+(w-dt)/1e4;if(g<0&&e.clockseq===void 0&&(s=s+1&16383),(g<0||f>lt)&&e.nsecs===void 0&&(w=0),w>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");lt=f,dt=w,ct=s,f+=122192928e5;let l=((f&268435455)*1e4+w)%4294967296;i[n++]=l>>>24&255,i[n++]=l>>>16&255,i[n++]=l>>>8&255,i[n++]=l&255;let x=f/4294967296*1e4&268435455;i[n++]=x>>>8&255,i[n++]=x&255,i[n++]=x>>>24&15|16,i[n++]=x>>>16&255,i[n++]=s>>>8|128,i[n++]=s&255;for(let v=0;v<6;++v)i[n+v]=u[v];return t||de(i)}var _r,ct,lt,dt,Wr,Fr=Z(()=>{at();we();lt=0,dt=0;Wr=li});function di(e){if(!ne(e))throw TypeError("Invalid UUID");let t,r=new Uint8Array(16);return r[0]=(t=parseInt(e.slice(0,8),16))>>>24,r[1]=t>>>16&255,r[2]=t>>>8&255,r[3]=t&255,r[4]=(t=parseInt(e.slice(9,13),16))>>>8,r[5]=t&255,r[6]=(t=parseInt(e.slice(14,18),16))>>>8,r[7]=t&255,r[8]=(t=parseInt(e.slice(19,23),16))>>>8,r[9]=t&255,r[10]=(t=parseInt(e.slice(24,36),16))/1099511627776&255,r[11]=t/4294967296&255,r[12]=t>>>24&255,r[13]=t>>>16&255,r[14]=t>>>8&255,r[15]=t&255,r}var Te,ht=Z(()=>{be();Te=di});function hi(e){e=unescape(encodeURIComponent(e));let t=[];for(let r=0;r{we();ht();pi="6ba7b810-9dad-11d1-80b4-00c04fd430c8",mi="6ba7b811-9dad-11d1-80b4-00c04fd430c8"});function gi(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),Hr.default.createHash("md5").update(e).digest()}var Hr,Br,Lr=Z(()=>{Hr=Ne(fe("crypto"));Br=gi});var yi,zr,Pr=Z(()=>{pt();Lr();yi=Oe("v3",48,Br),zr=yi});var Rr,mt,Jr=Z(()=>{Rr=Ne(fe("crypto")),mt={randomUUID:Rr.default.randomUUID}});function vi(e,t,r){if(mt.randomUUID&&!t&&!e)return mt.randomUUID();e=e||{};let n=e.random||(e.rng||$e)();if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,t){r=r||0;for(let i=0;i<16;++i)t[r+i]=n[i];return t}return de(n)}var Gr,Zr=Z(()=>{Jr();at();we();Gr=vi});function $i(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),Vr.default.createHash("sha1").update(e).digest()}var Vr,Qr,Xr=Z(()=>{Vr=Ne(fe("crypto"));Qr=$i});var bi,Kr,en=Z(()=>{pt();Xr();bi=Oe("v5",80,Qr),Kr=bi});var tn,rn=Z(()=>{tn="00000000-0000-0000-0000-000000000000"});function wi(e){if(!ne(e))throw TypeError("Invalid UUID");return parseInt(e.slice(14,15),16)}var nn,un=Z(()=>{be();nn=wi});var sn={};yt(sn,{NIL:()=>tn,parse:()=>Te,stringify:()=>Ir,v1:()=>Wr,v3:()=>zr,v4:()=>Gr,v5:()=>Kr,validate:()=>ne,version:()=>nn});var fn=Z(()=>{Fr();Pr();Zr();en();rn();un();be();we();ht()});var an=U((Wu,on)=>{var Oi=(fn(),$t(sn)),xi=on.exports;xi.uuid=function(){return Oi.v4()}});var dn=U((Fu,gt)=>{var{date:Si,duration:Ni}=Dt(),Mi={math:Rt(),array:ke(),number:nr(),url:ur(),string:or(),comparison:br(),object:Dr(),regex:qr(),uuid:an()},ln=["sortBy"];gt.exports.helpersToRemoveForJs=ln;var cn={date:Si,duration:Ni},ie;gt.exports.getJsHelperList=()=>{if(ie)return ie;ie={};for(let e of Object.values(Mi))for(let[t,r]of Object.entries(e))ie[t]=(...n)=>r(...n,{});for(let e of Object.keys(cn))ie[e]=cn[e];for(let e of ln)delete ie[e];return Object.freeze(ie),ie}});var ki={};yt(ki,{default:()=>Ai});var{getJsHelperList:ji}=dn(),Ai={...ji(),stripProtocol:helpersStripProtocol};return $t(ki);})(); /*! Bundled license information: is-buffer/index.js: diff --git a/packages/server/src/jsRunner/bundles/index-helpers.ts b/packages/server/src/jsRunner/bundles/index-helpers.ts index 91b9c8e821..a8992294a9 100644 --- a/packages/server/src/jsRunner/bundles/index-helpers.ts +++ b/packages/server/src/jsRunner/bundles/index-helpers.ts @@ -2,7 +2,7 @@ const { getJsHelperList, } = require("../../../../string-templates/src/helpers/list.js") -export const helpers = { +export default { ...getJsHelperList(), // pointing stripProtocol to a unexisting function to be able to declare it on isolated-vm // @ts-ignore diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index 1b1135e1f7..e36d5d595d 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -73,6 +73,10 @@ export class IsolatedVM implements VM { escape: querystring.escape, }) + const cryptoModule = this.registerCallbacks({ + randomUUID: crypto.randomUUID, + }) + this.addToContext({ helpersStripProtocol: new ivm.Callback((str: string) => { var parsed = url.parse(str) as any @@ -81,10 +85,6 @@ export class IsolatedVM implements VM { }), }) - const cryptoModule = this.registerCallbacks({ - randomUUID: crypto.randomUUID, - }) - const injectedRequire = `const require=function req(val) { switch (val) { case "url": return ${urlModule}; @@ -93,7 +93,9 @@ export class IsolatedVM implements VM { } }` const helpersSource = loadBundle(BundleType.HELPERS) - this.moduleHandler.registerModule(`${injectedRequire};${helpersSource}`) + this.moduleHandler.registerModule( + `${injectedRequire};${helpersSource};helpers=helpers.default` + ) return this } From 9ed6502681a57501e6f7d2fffabf532064238fa5 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 17:43:42 +0100 Subject: [PATCH 033/213] Fix ts-node and other runners --- packages/server/src/environment.ts | 1 + packages/server/src/jsRunner/bundles/index.ts | 11 ++++++----- scripts/build.js | 3 +++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index 8e6866d5e4..b6654d0a14 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -98,6 +98,7 @@ const environment = { JS_RUNNER_MEMORY_LIMIT: parseIntSafe(process.env.JS_RUNNER_MEMORY_LIMIT) || 64, LOG_JS_ERRORS: process.env.LOG_JS_ERRORS, + isBundled: process.env.BUNDLED, } // clean up any environment variable edge cases diff --git a/packages/server/src/jsRunner/bundles/index.ts b/packages/server/src/jsRunner/bundles/index.ts index 37e677ef46..e4b50c5e8d 100644 --- a/packages/server/src/jsRunner/bundles/index.ts +++ b/packages/server/src/jsRunner/bundles/index.ts @@ -8,20 +8,21 @@ export const enum BundleType { } const bundleSourceCode = { - [BundleType.HELPERS]: "../bundles/index-helpers.ivm.bundle.js", - [BundleType.BSON]: "../bundles/bson.ivm.bundle.js", + [BundleType.HELPERS]: "./index-helpers.ivm.bundle.js", + [BundleType.BSON]: "./bson.ivm.bundle.js", } export function loadBundle(type: BundleType) { - if (environment.isJest()) { + if (!environment.isBundled) { return fs.readFileSync(require.resolve(bundleSourceCode[type]), "utf-8") } + // If we are running from a built version, esbuild is configured to inject .ivm.bundle.js files as text switch (type) { case BundleType.HELPERS: - return require("../bundles/index-helpers.ivm.bundle.js") + return require("./index-helpers.ivm.bundle.js") case BundleType.BSON: - return require("../bundles/bson.ivm.bundle.js") + return require("./bson.ivm.bundle.js") default: utils.unreachable(type) } diff --git a/scripts/build.js b/scripts/build.js index ad31381684..73f07152a9 100755 --- a/scripts/build.js +++ b/scripts/build.js @@ -63,6 +63,9 @@ function runBuild(entry, outfile) { "graphql/*", "bson", ], + define: { + "process.env.BUNDLED": '"true"', + }, } build({ From 0902854bb00e8ea2a6160560e76304feb47fff08 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 17:44:24 +0100 Subject: [PATCH 034/213] Fix requires --- packages/server/src/jsRunner/vm/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index e36d5d595d..323b02f617 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -85,7 +85,7 @@ export class IsolatedVM implements VM { }), }) - const injectedRequire = `const require=function req(val) { + const injectedRequire = `require=function req(val) { switch (val) { case "url": return ${urlModule}; case "querystring": return ${querystringModule}; From 2d2d88f9881a6617f972a7c5261135bcd3f87273 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 23:37:30 +0100 Subject: [PATCH 035/213] Attempt quicker loading --- packages/server/src/jsRunner/bundles/index.ts | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/packages/server/src/jsRunner/bundles/index.ts b/packages/server/src/jsRunner/bundles/index.ts index e4b50c5e8d..ce19c15e09 100644 --- a/packages/server/src/jsRunner/bundles/index.ts +++ b/packages/server/src/jsRunner/bundles/index.ts @@ -7,23 +7,42 @@ export const enum BundleType { BSON = "bson", } -const bundleSourceCode = { - [BundleType.HELPERS]: "./index-helpers.ivm.bundle.js", - [BundleType.BSON]: "./bson.ivm.bundle.js", -} +const bundleSourceCode: Partial> = {} export function loadBundle(type: BundleType) { - if (!environment.isBundled) { - return fs.readFileSync(require.resolve(bundleSourceCode[type]), "utf-8") + let sourceCode = bundleSourceCode[type] + if (sourceCode) { + return sourceCode } - // If we are running from a built version, esbuild is configured to inject .ivm.bundle.js files as text - switch (type) { - case BundleType.HELPERS: - return require("./index-helpers.ivm.bundle.js") - case BundleType.BSON: - return require("./bson.ivm.bundle.js") - default: - utils.unreachable(type) + if (!environment.isBundled) { + let filePath + switch (type) { + case BundleType.HELPERS: + filePath = "./index-helpers.ivm.bundle.js" + break + case BundleType.BSON: + filePath = "./bson.ivm.bundle.js" + break + default: + throw utils.unreachable(type) + } + + sourceCode = fs.readFileSync(require.resolve(filePath), "utf-8") + } else { + // If we are running from a built version, esbuild is configured to inject .ivm.bundle.js files as text + switch (type) { + case BundleType.HELPERS: + sourceCode = require("./index-helpers.ivm.bundle.js") + break + case BundleType.BSON: + sourceCode = require("./bson.ivm.bundle.js") + break + default: + throw utils.unreachable(type) + } } + bundleSourceCode[type] = sourceCode + + return sourceCode } From f733d293dad5516714dafbf599a3435f5943ece5 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 23:44:24 +0100 Subject: [PATCH 036/213] Simplify loading --- packages/server/src/environment.ts | 1 - packages/server/src/jsRunner/bundles/index.ts | 33 +++---------------- scripts/build.js | 6 +--- 3 files changed, 6 insertions(+), 34 deletions(-) diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index b6654d0a14..8e6866d5e4 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -98,7 +98,6 @@ const environment = { JS_RUNNER_MEMORY_LIMIT: parseIntSafe(process.env.JS_RUNNER_MEMORY_LIMIT) || 64, LOG_JS_ERRORS: process.env.LOG_JS_ERRORS, - isBundled: process.env.BUNDLED, } // clean up any environment variable edge cases diff --git a/packages/server/src/jsRunner/bundles/index.ts b/packages/server/src/jsRunner/bundles/index.ts index ce19c15e09..9e2960807a 100644 --- a/packages/server/src/jsRunner/bundles/index.ts +++ b/packages/server/src/jsRunner/bundles/index.ts @@ -7,6 +7,10 @@ export const enum BundleType { BSON = "bson", } +const bundleSourceFile: Record = { + [BundleType.HELPERS]: "./index-helpers.ivm.bundle.js", + [BundleType.BSON]: "./bson.ivm.bundle.js", +} const bundleSourceCode: Partial> = {} export function loadBundle(type: BundleType) { @@ -15,34 +19,7 @@ export function loadBundle(type: BundleType) { return sourceCode } - if (!environment.isBundled) { - let filePath - switch (type) { - case BundleType.HELPERS: - filePath = "./index-helpers.ivm.bundle.js" - break - case BundleType.BSON: - filePath = "./bson.ivm.bundle.js" - break - default: - throw utils.unreachable(type) - } - - sourceCode = fs.readFileSync(require.resolve(filePath), "utf-8") - } else { - // If we are running from a built version, esbuild is configured to inject .ivm.bundle.js files as text - switch (type) { - case BundleType.HELPERS: - sourceCode = require("./index-helpers.ivm.bundle.js") - break - case BundleType.BSON: - sourceCode = require("./bson.ivm.bundle.js") - break - default: - throw utils.unreachable(type) - } - } + sourceCode = fs.readFileSync(require.resolve(bundleSourceFile[type]), "utf-8") bundleSourceCode[type] = sourceCode - return sourceCode } diff --git a/scripts/build.js b/scripts/build.js index 73f07152a9..0c0c8f1548 100755 --- a/scripts/build.js +++ b/scripts/build.js @@ -49,7 +49,6 @@ function runBuild(entry, outfile) { preserveSymlinks: true, loader: { ".svelte": "copy", - ".ivm.bundle.js": "text", }, metafile: true, external: [ @@ -63,9 +62,6 @@ function runBuild(entry, outfile) { "graphql/*", "bson", ], - define: { - "process.env.BUNDLED": '"true"', - }, } build({ @@ -73,7 +69,7 @@ function runBuild(entry, outfile) { platform: "node", outfile, }).then(result => { - glob(`${process.cwd()}/src/**/*.hbs`, {}, (err, files) => { + glob(`${process.cwd()}/src/**/*.{hbs,ivm.bundle.js}`, {}, (err, files) => { for (const file of files) { fs.copyFileSync(file, `${process.cwd()}/dist/${path.basename(file)}`) } From a6c50500fe2797cbaa46da00e10ad217672cfe34 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 13 Feb 2024 23:49:17 +0100 Subject: [PATCH 037/213] Release script --- packages/server/src/jsRunner/vm/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index 323b02f617..497cff1058 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -178,7 +178,7 @@ export class IsolatedVM implements VM { const script = this.isolate.compileScriptSync(code) - script.runSync(this.vm, { timeout: this.invocationTimeout }) + script.runSync(this.vm, { timeout: this.invocationTimeout, release: true }) // We can't rely on the script run result as it will not work for non-transferable values const result = this.getFromContext(this.resultKey) From 7d6e49f8ca0bc6b6aadf5e3417d0f71a391396d9 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 14 Feb 2024 11:44:24 +0100 Subject: [PATCH 038/213] Inject only on init --- packages/server/src/jsRunner/vm/index.ts | 27 +++++++----------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index 497cff1058..e76a511409 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -15,18 +15,6 @@ class ExecutionTimeoutError extends Error { } } -class ModuleHandler { - private modules: string[] = [] - - registerModule(code: string) { - this.modules.push(code) - } - - generateImports() { - return this.modules.join(";") - } -} - export class IsolatedVM implements VM { private isolate: ivm.Isolate private vm: ivm.Context @@ -37,8 +25,6 @@ export class IsolatedVM implements VM { // By default the wrapper returns itself private codeWrapper: (code: string) => string = code => code - private moduleHandler = new ModuleHandler() - private readonly resultKey = "results" constructor({ @@ -93,9 +79,11 @@ export class IsolatedVM implements VM { } }` const helpersSource = loadBundle(BundleType.HELPERS) - this.moduleHandler.registerModule( + const script = this.isolate.compileScriptSync( `${injectedRequire};${helpersSource};helpers=helpers.default` ) + script.runSync(this.vm, { timeout: this.invocationTimeout, release: true }) + return this } @@ -157,7 +145,10 @@ export class IsolatedVM implements VM { .toString() .replace(/TextDecoderMock/, "TextDecoder") - this.moduleHandler.registerModule(`${textDecoderPolyfill};${bsonSource}`) + const script = this.isolate.compileScriptSync( + `${textDecoderPolyfill};${bsonSource}` + ) + script.runSync(this.vm, { timeout: this.invocationTimeout, release: true }) return this } @@ -172,9 +163,7 @@ export class IsolatedVM implements VM { } } - code = `${this.moduleHandler.generateImports()};results.out=${this.codeWrapper( - code - )}` + code = `results.out=${this.codeWrapper(code)}` const script = this.isolate.compileScriptSync(code) From bb6500cc91314a1d178a155f3f9369826dbf64c2 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 14 Feb 2024 11:47:34 +0100 Subject: [PATCH 039/213] Avoid crossing results --- packages/server/src/jsRunner/vm/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index e76a511409..e8eedd9c68 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -26,6 +26,7 @@ export class IsolatedVM implements VM { private codeWrapper: (code: string) => string = code => code private readonly resultKey = "results" + private runResultKey: string constructor({ memoryLimit, @@ -41,8 +42,9 @@ export class IsolatedVM implements VM { this.jail = this.vm.global this.jail.setSync("global", this.jail.derefInto()) + this.runResultKey = crypto.randomUUID() this.addToContext({ - [this.resultKey]: { out: "" }, + [this.resultKey]: { [this.runResultKey]: "" }, }) this.invocationTimeout = invocationTimeout @@ -163,7 +165,7 @@ export class IsolatedVM implements VM { } } - code = `results.out=${this.codeWrapper(code)}` + code = `results['${this.runResultKey}']=${this.codeWrapper(code)}` const script = this.isolate.compileScriptSync(code) @@ -171,7 +173,7 @@ export class IsolatedVM implements VM { // We can't rely on the script run result as it will not work for non-transferable values const result = this.getFromContext(this.resultKey) - return result.out + return result[this.runResultKey] } private registerCallbacks(functions: Record) { From 85aeaff891283e4714de7f7a39eb2d78ff86aaff Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 14 Feb 2024 12:52:20 +0100 Subject: [PATCH 040/213] Shave time on release --- packages/server/src/jsRunner/vm/index.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index e8eedd9c68..0285af8620 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -84,7 +84,11 @@ export class IsolatedVM implements VM { const script = this.isolate.compileScriptSync( `${injectedRequire};${helpersSource};helpers=helpers.default` ) - script.runSync(this.vm, { timeout: this.invocationTimeout, release: true }) + + script.runSync(this.vm, { timeout: this.invocationTimeout, release: false }) + new Promise(() => { + script.release() + }) return this } @@ -150,7 +154,10 @@ export class IsolatedVM implements VM { const script = this.isolate.compileScriptSync( `${textDecoderPolyfill};${bsonSource}` ) - script.runSync(this.vm, { timeout: this.invocationTimeout, release: true }) + script.runSync(this.vm, { timeout: this.invocationTimeout, release: false }) + new Promise(() => { + script.release() + }) return this } @@ -169,7 +176,10 @@ export class IsolatedVM implements VM { const script = this.isolate.compileScriptSync(code) - script.runSync(this.vm, { timeout: this.invocationTimeout, release: true }) + script.runSync(this.vm, { timeout: this.invocationTimeout, release: false }) + new Promise(() => { + script.release() + }) // We can't rely on the script run result as it will not work for non-transferable values const result = this.getFromContext(this.resultKey) @@ -213,7 +223,10 @@ export class IsolatedVM implements VM { private getFromContext(key: string) { const ref = this.vm.global.getSync(key, { reference: true }) const result = ref.copySync() - ref.release() + + new Promise(() => { + ref.release() + }) return result } } From 4426f84e2df5ab291785d97286bc9956a9ffc3f3 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 14 Feb 2024 16:57:59 +0000 Subject: [PATCH 041/213] Use constants for icon info rather than component definitions --- .../FieldSetting.svelte | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/FieldSetting.svelte b/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/FieldSetting.svelte index 3f2afbfe8d..668f2f7d59 100644 --- a/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/FieldSetting.svelte +++ b/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/FieldSetting.svelte @@ -1,15 +1,25 @@
@@ -42,7 +45,7 @@ on:change >
- + {item.field}
From 0c66f2d3995643694612532e8c0479de33cb9751 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 15 Feb 2024 09:17:58 +0000 Subject: [PATCH 042/213] Bump account portal --- packages/account-portal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/account-portal b/packages/account-portal index 1ba8414bed..8c446c4ba3 160000 --- a/packages/account-portal +++ b/packages/account-portal @@ -1 +1 @@ -Subproject commit 1ba8414bed14439512153cf851086146a80560f5 +Subproject commit 8c446c4ba385592127fa31755d3b64467b291882 From 36e1a20c03476fe7139982b46f86957ec8d2ba5c Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Thu, 15 Feb 2024 13:45:08 +0000 Subject: [PATCH 043/213] Revert "Revert "Fix updating users via cross-service comms (public API)"" --- .../server/src/utilities/workerRequests.ts | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/server/src/utilities/workerRequests.ts b/packages/server/src/utilities/workerRequests.ts index 69ce58c8a9..5612084216 100644 --- a/packages/server/src/utilities/workerRequests.ts +++ b/packages/server/src/utilities/workerRequests.ts @@ -14,12 +14,23 @@ export function request(ctx?: Ctx, request?: any) { if (!request.headers) { request.headers = {} } + if (!ctx) { request.headers[constants.Header.API_KEY] = coreEnv.INTERNAL_API_KEY - if (tenancy.isTenantIdSet()) { - request.headers[constants.Header.TENANT_ID] = tenancy.getTenantId() + } else if (ctx.headers) { + // copy all Budibase utilised headers over - copying everything can have + // side effects like requests being rejected due to odd content types etc + for (let header of Object.values(constants.Header)) { + if (ctx.headers[header]) { + request.headers[header] = ctx.headers[header] + } } } + + // apply tenancy if its available + if (tenancy.isTenantIdSet()) { + request.headers[constants.Header.TENANT_ID] = tenancy.getTenantId() + } if (request.body && Object.keys(request.body).length > 0) { request.headers["Content-Type"] = "application/json" request.body = @@ -29,9 +40,6 @@ export function request(ctx?: Ctx, request?: any) { } else { delete request.body } - if (ctx && ctx.headers) { - request.headers = ctx.headers - } // add x-budibase-correlation-id header logging.correlation.setHeader(request.headers) @@ -54,7 +62,7 @@ async function checkResponse( } const msg = `Unable to ${errorMsg} - ${responseErrorMessage}` if (ctx) { - ctx.throw(msg, response.status) + ctx.throw(response.status || 500, msg) } else { throw msg } From dde8f778774ab756edb51e1c4e2a208e80b70629 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Thu, 15 Feb 2024 14:48:47 +0000 Subject: [PATCH 044/213] Type workerRequests.ts --- .../src/logging/correlation/correlation.ts | 13 +++- .../server/src/utilities/workerRequests.ts | 78 ++++++++++++++----- 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/packages/backend-core/src/logging/correlation/correlation.ts b/packages/backend-core/src/logging/correlation/correlation.ts index 0498bd43d5..2ee02c16a9 100644 --- a/packages/backend-core/src/logging/correlation/correlation.ts +++ b/packages/backend-core/src/logging/correlation/correlation.ts @@ -1,10 +1,19 @@ +import { HeaderInit, Headers } from "node-fetch" import { Header } from "../../constants" const correlator = require("correlation-id") -export const setHeader = (headers: any) => { +export const setHeader = (headers: HeaderInit) => { const correlationId = correlator.getId() - if (correlationId) { + if (!correlationId) { + return + } + + if (headers instanceof Headers) { + headers.set(Header.CORRELATION_ID, correlationId) + } else if (Array.isArray(headers)) { + headers.push([Header.CORRELATION_ID, correlationId]) + } else { headers[Header.CORRELATION_ID] = correlationId } } diff --git a/packages/server/src/utilities/workerRequests.ts b/packages/server/src/utilities/workerRequests.ts index 5612084216..d3c5cad161 100644 --- a/packages/server/src/utilities/workerRequests.ts +++ b/packages/server/src/utilities/workerRequests.ts @@ -1,4 +1,10 @@ -import { Response, default as fetch } from "node-fetch" +import { + Response, + default as fetch, + type RequestInit, + Headers, + HeadersInit, +} from "node-fetch" import env from "../environment" import { checkSlashesInUrl } from "./index" import { @@ -10,29 +16,61 @@ import { } from "@budibase/backend-core" import { Ctx, User, EmailInvite } from "@budibase/types" -export function request(ctx?: Ctx, request?: any) { - if (!request.headers) { - request.headers = {} +function ensureHeadersIsObject(headers: HeadersInit | undefined): Headers { + if (headers instanceof Headers) { + return headers } + const headersObj = new Headers() + if (headers === undefined) { + return headersObj + } + + if (Array.isArray(headers)) { + for (const [key, value] of headers) { + headersObj.append(key, value) + } + } else { + for (const key in headers) { + headersObj.append(key, headers[key]) + } + } + return headersObj +} + +export function request(request: RequestInit & { ctx?: Ctx }): RequestInit { + const ctx = request.ctx + request.headers = ensureHeadersIsObject(request.headers) + if (!ctx) { - request.headers[constants.Header.API_KEY] = coreEnv.INTERNAL_API_KEY + if (coreEnv.INTERNAL_API_KEY) { + request.headers.set(constants.Header.API_KEY, coreEnv.INTERNAL_API_KEY) + } } else if (ctx.headers) { // copy all Budibase utilised headers over - copying everything can have // side effects like requests being rejected due to odd content types etc for (let header of Object.values(constants.Header)) { - if (ctx.headers[header]) { - request.headers[header] = ctx.headers[header] + const value = ctx.headers[header] + if (value === undefined) { + continue + } + + if (Array.isArray(value)) { + for (let v of value) { + request.headers.append(header, v) + } + } else { + request.headers.set(header, value) } } } // apply tenancy if its available if (tenancy.isTenantIdSet()) { - request.headers[constants.Header.TENANT_ID] = tenancy.getTenantId() + request.headers.set(constants.Header.TENANT_ID, tenancy.getTenantId()) } if (request.body && Object.keys(request.body).length > 0) { - request.headers["Content-Type"] = "application/json" + request.headers.set("Content-Type", "application/json") request.body = typeof request.body === "object" ? JSON.stringify(request.body) @@ -44,6 +82,7 @@ export function request(ctx?: Ctx, request?: any) { // add x-budibase-correlation-id header logging.correlation.setHeader(request.headers) + delete request.ctx return request } @@ -93,9 +132,9 @@ export async function sendSmtpEmail({ // tenant ID will be set in header const response = await fetch( checkSlashesInUrl(env.WORKER_URL + `/api/global/email/send`), - request(undefined, { + request({ method: "POST", - body: { + body: JSON.stringify({ email: to, from, contents, @@ -105,7 +144,7 @@ export async function sendSmtpEmail({ purpose: "custom", automation, invite, - }, + }), }) ) return checkResponse(response, "send email") @@ -115,7 +154,8 @@ export async function removeAppFromUserRoles(ctx: Ctx, appId: string) { const prodAppId = dbCore.getProdAppID(appId) const response = await fetch( checkSlashesInUrl(env.WORKER_URL + `/api/global/roles/${prodAppId}`), - request(ctx, { + request({ + ctx, method: "DELETE", }) ) @@ -126,7 +166,7 @@ export async function allGlobalUsers(ctx: Ctx) { const response = await fetch( checkSlashesInUrl(env.WORKER_URL + "/api/global/users"), // we don't want to use API key when getting self - request(ctx, { method: "GET" }) + request({ ctx, method: "GET" }) ) return checkResponse(response, "get users", { ctx }) } @@ -135,7 +175,7 @@ export async function saveGlobalUser(ctx: Ctx) { const response = await fetch( checkSlashesInUrl(env.WORKER_URL + "/api/global/users"), // we don't want to use API key when getting self - request(ctx, { method: "POST", body: ctx.request.body }) + request({ ctx, method: "POST", body: ctx.request.body }) ) return checkResponse(response, "save user", { ctx }) } @@ -146,7 +186,7 @@ export async function deleteGlobalUser(ctx: Ctx) { env.WORKER_URL + `/api/global/users/${ctx.params.userId}` ), // we don't want to use API key when getting self - request(ctx, { method: "DELETE" }) + request({ ctx, method: "DELETE" }) ) return checkResponse(response, "delete user", { ctx }) } @@ -157,7 +197,7 @@ export async function readGlobalUser(ctx: Ctx): Promise { env.WORKER_URL + `/api/global/users/${ctx.params.userId}` ), // we don't want to use API key when getting self - request(ctx, { method: "GET" }) + request({ ctx, method: "GET" }) ) return checkResponse(response, "get user", { ctx }) } @@ -167,7 +207,7 @@ export async function getChecklist(): Promise<{ }> { const response = await fetch( checkSlashesInUrl(env.WORKER_URL + "/api/global/configs/checklist"), - request(undefined, { method: "GET" }) + request({ method: "GET" }) ) return checkResponse(response, "get checklist") } @@ -175,7 +215,7 @@ export async function getChecklist(): Promise<{ export async function generateApiKey(userId: string) { const response = await fetch( checkSlashesInUrl(env.WORKER_URL + "/api/global/self/api_key"), - request(undefined, { method: "POST", body: { userId } }) + request({ method: "POST", body: JSON.stringify({ userId }) }) ) return checkResponse(response, "generate API key") } From 1f4a254ec5449e2e04797ce3fa904cf14048ccde Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 15 Feb 2024 15:47:56 +0000 Subject: [PATCH 045/213] Fix for integration test, make sure to carry auth headers over correctly. --- packages/server/src/utilities/workerRequests.ts | 9 +++++++++ packages/shared-core/src/constants/api.ts | 1 + 2 files changed, 10 insertions(+) diff --git a/packages/server/src/utilities/workerRequests.ts b/packages/server/src/utilities/workerRequests.ts index 5612084216..b5c3bfcd4a 100644 --- a/packages/server/src/utilities/workerRequests.ts +++ b/packages/server/src/utilities/workerRequests.ts @@ -7,6 +7,7 @@ import { tenancy, logging, env as coreEnv, + utils, } from "@budibase/backend-core" import { Ctx, User, EmailInvite } from "@budibase/types" @@ -25,6 +26,14 @@ export function request(ctx?: Ctx, request?: any) { request.headers[header] = ctx.headers[header] } } + // be specific about auth headers + const cookie = ctx.headers[constants.Header.COOKIE], + apiKey = ctx.headers[constants.Header.API_KEY] + if (cookie) { + request.headers[constants.Header.COOKIE] = cookie + } else if (apiKey) { + request.headers[constants.Header.API_KEY] = apiKey + } } // apply tenancy if its available diff --git a/packages/shared-core/src/constants/api.ts b/packages/shared-core/src/constants/api.ts index d6633649e6..f63849bf3d 100644 --- a/packages/shared-core/src/constants/api.ts +++ b/packages/shared-core/src/constants/api.ts @@ -16,4 +16,5 @@ export enum Header { CORRELATION_ID = "x-budibase-correlation-id", AUTHORIZATION = "authorization", MIGRATING_APP = "x-budibase-migrating-app", + COOKIE = "cookie", } From d5932605b7a8bcdcdd203907303c7af1f58f1511 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 15 Feb 2024 15:49:12 +0000 Subject: [PATCH 046/213] Fixing an issue where app routing information was requested before the app store was fully brought online, meaning that routing information wasn't always successfully retrieved. --- packages/builder/src/stores/builder/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/stores/builder/index.js b/packages/builder/src/stores/builder/index.js index 36af7e7435..bac9fb8826 100644 --- a/packages/builder/src/stores/builder/index.js +++ b/packages/builder/src/stores/builder/index.js @@ -92,12 +92,13 @@ const resetBuilderHistory = () => { export const initialise = async pkg => { const { application } = pkg + // must be first operation to make sure subsequent requests have correct app ID + appStore.syncAppPackage(pkg) await Promise.all([ appStore.syncAppRoutes(), componentStore.refreshDefinitions(application?.appId), ]) builderStore.init(application) - appStore.syncAppPackage(pkg) navigationStore.syncAppNavigation(application?.navigation) themeStore.syncAppTheme(application) screenStore.syncAppScreens(pkg) From e4b03308664f5d0054a7ca94fb55b9e89f92e8cf Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Thu, 15 Feb 2024 15:49:30 +0000 Subject: [PATCH 047/213] Simplify the typing of workerRequests.ts --- .../src/logging/correlation/correlation.ts | 12 +--- .../server/src/utilities/workerRequests.ts | 70 +++++++++---------- 2 files changed, 37 insertions(+), 45 deletions(-) diff --git a/packages/backend-core/src/logging/correlation/correlation.ts b/packages/backend-core/src/logging/correlation/correlation.ts index 2ee02c16a9..13cc7aff8f 100644 --- a/packages/backend-core/src/logging/correlation/correlation.ts +++ b/packages/backend-core/src/logging/correlation/correlation.ts @@ -1,21 +1,13 @@ -import { HeaderInit, Headers } from "node-fetch" import { Header } from "../../constants" const correlator = require("correlation-id") -export const setHeader = (headers: HeaderInit) => { +export const setHeader = (headers: Record) => { const correlationId = correlator.getId() if (!correlationId) { return } - - if (headers instanceof Headers) { - headers.set(Header.CORRELATION_ID, correlationId) - } else if (Array.isArray(headers)) { - headers.push([Header.CORRELATION_ID, correlationId]) - } else { - headers[Header.CORRELATION_ID] = correlationId - } + headers[Header.CORRELATION_ID] = correlationId } export function getId() { diff --git a/packages/server/src/utilities/workerRequests.ts b/packages/server/src/utilities/workerRequests.ts index d3c5cad161..ce43c1aa44 100644 --- a/packages/server/src/utilities/workerRequests.ts +++ b/packages/server/src/utilities/workerRequests.ts @@ -38,15 +38,24 @@ function ensureHeadersIsObject(headers: HeadersInit | undefined): Headers { return headersObj } -export function request(request: RequestInit & { ctx?: Ctx }): RequestInit { - const ctx = request.ctx - request.headers = ensureHeadersIsObject(request.headers) +interface Request { + ctx?: Ctx + method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" + headers?: { [key: string]: string } + body?: { [key: string]: any } +} - if (!ctx) { - if (coreEnv.INTERNAL_API_KEY) { - request.headers.set(constants.Header.API_KEY, coreEnv.INTERNAL_API_KEY) - } - } else if (ctx.headers) { +export function createRequest(request: Request): RequestInit { + const headers: Record = {} + const requestInit: RequestInit = { + method: request.method, + } + + const ctx = request.ctx + + if (!ctx && coreEnv.INTERNAL_API_KEY) { + headers[constants.Header.API_KEY] = coreEnv.INTERNAL_API_KEY + } else if (ctx && ctx.headers) { // copy all Budibase utilised headers over - copying everything can have // side effects like requests being rejected due to odd content types etc for (let header of Object.values(constants.Header)) { @@ -56,34 +65,25 @@ export function request(request: RequestInit & { ctx?: Ctx }): RequestInit { } if (Array.isArray(value)) { - for (let v of value) { - request.headers.append(header, v) - } + headers[header] = value[0] } else { - request.headers.set(header, value) + headers[header] = value } } } // apply tenancy if its available if (tenancy.isTenantIdSet()) { - request.headers.set(constants.Header.TENANT_ID, tenancy.getTenantId()) + headers[constants.Header.TENANT_ID] = tenancy.getTenantId() } + if (request.body && Object.keys(request.body).length > 0) { - request.headers.set("Content-Type", "application/json") - request.body = - typeof request.body === "object" - ? JSON.stringify(request.body) - : request.body - } else { - delete request.body + headers["Content-Type"] = "application/json" + requestInit.body = JSON.stringify(request.body) } - // add x-budibase-correlation-id header - logging.correlation.setHeader(request.headers) - - delete request.ctx - return request + logging.correlation.setHeader(headers) + return requestInit } async function checkResponse( @@ -132,9 +132,9 @@ export async function sendSmtpEmail({ // tenant ID will be set in header const response = await fetch( checkSlashesInUrl(env.WORKER_URL + `/api/global/email/send`), - request({ + createRequest({ method: "POST", - body: JSON.stringify({ + body: { email: to, from, contents, @@ -144,7 +144,7 @@ export async function sendSmtpEmail({ purpose: "custom", automation, invite, - }), + }, }) ) return checkResponse(response, "send email") @@ -154,7 +154,7 @@ export async function removeAppFromUserRoles(ctx: Ctx, appId: string) { const prodAppId = dbCore.getProdAppID(appId) const response = await fetch( checkSlashesInUrl(env.WORKER_URL + `/api/global/roles/${prodAppId}`), - request({ + createRequest({ ctx, method: "DELETE", }) @@ -166,7 +166,7 @@ export async function allGlobalUsers(ctx: Ctx) { const response = await fetch( checkSlashesInUrl(env.WORKER_URL + "/api/global/users"), // we don't want to use API key when getting self - request({ ctx, method: "GET" }) + createRequest({ ctx, method: "GET" }) ) return checkResponse(response, "get users", { ctx }) } @@ -175,7 +175,7 @@ export async function saveGlobalUser(ctx: Ctx) { const response = await fetch( checkSlashesInUrl(env.WORKER_URL + "/api/global/users"), // we don't want to use API key when getting self - request({ ctx, method: "POST", body: ctx.request.body }) + createRequest({ ctx, method: "POST", body: ctx.request.body }) ) return checkResponse(response, "save user", { ctx }) } @@ -186,7 +186,7 @@ export async function deleteGlobalUser(ctx: Ctx) { env.WORKER_URL + `/api/global/users/${ctx.params.userId}` ), // we don't want to use API key when getting self - request({ ctx, method: "DELETE" }) + createRequest({ ctx, method: "DELETE" }) ) return checkResponse(response, "delete user", { ctx }) } @@ -197,7 +197,7 @@ export async function readGlobalUser(ctx: Ctx): Promise { env.WORKER_URL + `/api/global/users/${ctx.params.userId}` ), // we don't want to use API key when getting self - request({ ctx, method: "GET" }) + createRequest({ ctx, method: "GET" }) ) return checkResponse(response, "get user", { ctx }) } @@ -207,7 +207,7 @@ export async function getChecklist(): Promise<{ }> { const response = await fetch( checkSlashesInUrl(env.WORKER_URL + "/api/global/configs/checklist"), - request({ method: "GET" }) + createRequest({ method: "GET" }) ) return checkResponse(response, "get checklist") } @@ -215,7 +215,7 @@ export async function getChecklist(): Promise<{ export async function generateApiKey(userId: string) { const response = await fetch( checkSlashesInUrl(env.WORKER_URL + "/api/global/self/api_key"), - request({ method: "POST", body: JSON.stringify({ userId }) }) + createRequest({ method: "POST", body: { userId } }) ) return checkResponse(response, "generate API key") } From b4669b32f00158e72b637cf13747c5b2a26618f6 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Thu, 15 Feb 2024 15:52:06 +0000 Subject: [PATCH 048/213] Fix build. --- packages/server/src/api/controllers/dev.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/server/src/api/controllers/dev.ts b/packages/server/src/api/controllers/dev.ts index d8c26725f1..497da088c6 100644 --- a/packages/server/src/api/controllers/dev.ts +++ b/packages/server/src/api/controllers/dev.ts @@ -1,7 +1,7 @@ import fetch from "node-fetch" import env from "../../environment" import { checkSlashesInUrl } from "../../utilities" -import { request } from "../../utilities/workerRequests" +import { createRequest } from "../../utilities/workerRequests" import { clearLock as redisClearLock } from "../../utilities/redis" import { DocumentType } from "../../db/utils" import { @@ -13,14 +13,19 @@ import { } from "@budibase/backend-core" import { App } from "@budibase/types" -async function redirect(ctx: any, method: string, path: string = "global") { +async function redirect( + ctx: any, + method: "GET" | "POST" | "DELETE", + path: string = "global" +) { const { devPath } = ctx.params const queryString = ctx.originalUrl.split("?")[1] || "" const response = await fetch( checkSlashesInUrl( `${env.WORKER_URL}/api/${path}/${devPath}?${queryString}` ), - request(ctx, { + createRequest({ + ctx, method, body: ctx.request.body, }) From c2c0108e4fd7f6595f7ddda547b46f713fa301c3 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Thu, 15 Feb 2024 16:12:47 +0000 Subject: [PATCH 049/213] Fix build (again). --- packages/server/src/utilities/workerRequests.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/server/src/utilities/workerRequests.ts b/packages/server/src/utilities/workerRequests.ts index acf7515784..def3ffe9cf 100644 --- a/packages/server/src/utilities/workerRequests.ts +++ b/packages/server/src/utilities/workerRequests.ts @@ -75,9 +75,13 @@ export function createRequest(request: Request): RequestInit { const cookie = ctx.headers[constants.Header.COOKIE], apiKey = ctx.headers[constants.Header.API_KEY] if (cookie) { - request.headers[constants.Header.COOKIE] = cookie + headers[constants.Header.COOKIE] = cookie } else if (apiKey) { - request.headers[constants.Header.API_KEY] = apiKey + if (Array.isArray(apiKey)) { + headers[constants.Header.API_KEY] = apiKey[0] + } else { + headers[constants.Header.API_KEY] = apiKey + } } } From 32815d8d9bec6c1efe58f4fcdcd226b1e47364ce Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 15 Feb 2024 16:28:59 +0000 Subject: [PATCH 050/213] Quick readability enhancement. --- packages/server/src/utilities/workerRequests.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/server/src/utilities/workerRequests.ts b/packages/server/src/utilities/workerRequests.ts index def3ffe9cf..054514ab59 100644 --- a/packages/server/src/utilities/workerRequests.ts +++ b/packages/server/src/utilities/workerRequests.ts @@ -64,12 +64,7 @@ export function createRequest(request: Request): RequestInit { if (value === undefined) { continue } - - if (Array.isArray(value)) { - headers[header] = value[0] - } else { - headers[header] = value - } + headers[header] = Array.isArray(value) ? value[0] : value } // be specific about auth headers const cookie = ctx.headers[constants.Header.COOKIE], @@ -77,11 +72,9 @@ export function createRequest(request: Request): RequestInit { if (cookie) { headers[constants.Header.COOKIE] = cookie } else if (apiKey) { - if (Array.isArray(apiKey)) { - headers[constants.Header.API_KEY] = apiKey[0] - } else { - headers[constants.Header.API_KEY] = apiKey - } + headers[constants.Header.API_KEY] = Array.isArray(apiKey) + ? apiKey[0] + : apiKey } } From dd4ea4be95c733636f42ed8161f395c2217699f8 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Thu, 15 Feb 2024 16:44:19 +0000 Subject: [PATCH 051/213] Nothing to see here, carry on. --- .../server/src/utilities/workerRequests.ts | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/packages/server/src/utilities/workerRequests.ts b/packages/server/src/utilities/workerRequests.ts index 054514ab59..91340c8d78 100644 --- a/packages/server/src/utilities/workerRequests.ts +++ b/packages/server/src/utilities/workerRequests.ts @@ -17,28 +17,6 @@ import { } from "@budibase/backend-core" import { Ctx, User, EmailInvite } from "@budibase/types" -function ensureHeadersIsObject(headers: HeadersInit | undefined): Headers { - if (headers instanceof Headers) { - return headers - } - - const headersObj = new Headers() - if (headers === undefined) { - return headersObj - } - - if (Array.isArray(headers)) { - for (const [key, value] of headers) { - headersObj.append(key, value) - } - } else { - for (const key in headers) { - headersObj.append(key, headers[key]) - } - } - return headersObj -} - interface Request { ctx?: Ctx method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" @@ -89,6 +67,7 @@ export function createRequest(request: Request): RequestInit { } logging.correlation.setHeader(headers) + requestInit.headers = headers return requestInit } From 5a29bb7ebafce2ee734c3ba972a0372ef01017e1 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 15 Feb 2024 17:28:54 +0000 Subject: [PATCH 052/213] Bump version to 2.19.5 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 4940336b29..596fb434bc 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.19.4", + "version": "2.19.5", "npmClient": "yarn", "packages": [ "packages/*", From 9a9fa3c7165bf95ceec9c5226c53d48bc8d7d42f Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 16 Feb 2024 10:46:36 +0000 Subject: [PATCH 053/213] Updating CouchDB with the Budi CLI, making sure the service is always up to date, as well as removing pull policy. --- hosting/docker-compose.yaml | 1 - packages/cli/src/hosting/update.ts | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hosting/docker-compose.yaml b/hosting/docker-compose.yaml index 36b88466fe..a72b36aef1 100644 --- a/hosting/docker-compose.yaml +++ b/hosting/docker-compose.yaml @@ -98,7 +98,6 @@ services: couchdb-service: restart: unless-stopped image: budibase/couchdb - pull_policy: always environment: - COUCHDB_PASSWORD=${COUCH_DB_PASSWORD} - COUCHDB_USER=${COUCH_DB_USER} diff --git a/packages/cli/src/hosting/update.ts b/packages/cli/src/hosting/update.ts index ca0ecce615..cf70140224 100644 --- a/packages/cli/src/hosting/update.ts +++ b/packages/cli/src/hosting/update.ts @@ -13,7 +13,12 @@ import { COMPOSE_PATH } from "./makeFiles" import { info, success } from "../utils" import { start } from "./start" -const BB_COMPOSE_SERVICES = ["app-service", "worker-service", "proxy-service"] +const BB_COMPOSE_SERVICES = [ + "app-service", + "worker-service", + "proxy-service", + "couchdb-service", +] const BB_SINGLE_SERVICE = ["budibase"] export async function update() { From 30abf188a3aa0e03442ffe8d5b4b29340e0ce4bc Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 16 Feb 2024 15:13:26 +0000 Subject: [PATCH 054/213] Bail out if server startup fails. --- hosting/single/Dockerfile | 2 +- packages/server/src/app.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile index a928766541..f89967cb0b 100644 --- a/hosting/single/Dockerfile +++ b/hosting/single/Dockerfile @@ -38,7 +38,7 @@ COPY packages/worker/pm2.config.js packages/worker/pm2.config.js COPY packages/string-templates packages/string-templates -FROM budicouch as runner +FROM budibase/couchdb as runner ARG TARGETARCH ENV TARGETARCH $TARGETARCH #TARGETBUILD can be set to single (for single docker image) or aas (for azure app service) diff --git a/packages/server/src/app.ts b/packages/server/src/app.ts index f6f1780030..4e84422dec 100644 --- a/packages/server/src/app.ts +++ b/packages/server/src/app.ts @@ -26,6 +26,7 @@ async function start() { start().catch(err => { console.error(`Failed server startup - ${err.message}`) + throw err }) export function getServer() { From 364579acc444952885e3e5a8a09f3f653a77cd28 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 16 Feb 2024 15:41:36 +0000 Subject: [PATCH 055/213] Fixing an issue when invalid version is supplied (not semver) shouldn't crash server. --- packages/backend-core/src/installation.ts | 45 ++++++++++++++--------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/packages/backend-core/src/installation.ts b/packages/backend-core/src/installation.ts index ca35b926fb..83166880cc 100644 --- a/packages/backend-core/src/installation.ts +++ b/packages/backend-core/src/installation.ts @@ -6,6 +6,7 @@ import * as context from "./context" import semver from "semver" import { bustCache, withCache, TTL, CacheKey } from "./cache/generic" import environment from "./environment" +import { logAlert } from "./logging" export const getInstall = async (): Promise => { return withCache(CacheKey.INSTALLATION, TTL.ONE_DAY, getInstallFromDB, { @@ -80,27 +81,35 @@ export const checkInstallVersion = async (): Promise => { const currentVersion = install.version const newVersion = environment.VERSION - if (currentVersion !== newVersion) { - const isUpgrade = semver.gt(newVersion, currentVersion) - const isDowngrade = semver.lt(newVersion, currentVersion) + try { + if (currentVersion !== newVersion) { + const isUpgrade = semver.gt(newVersion, currentVersion) + const isDowngrade = semver.lt(newVersion, currentVersion) - const success = await updateVersion(newVersion) + const success = await updateVersion(newVersion) - if (success) { - await context.doInIdentityContext( - { - _id: install.installId, - type: IdentityType.INSTALLATION, - }, - async () => { - if (isUpgrade) { - await events.installation.upgraded(currentVersion, newVersion) - } else if (isDowngrade) { - await events.installation.downgraded(currentVersion, newVersion) + if (success) { + await context.doInIdentityContext( + { + _id: install.installId, + type: IdentityType.INSTALLATION, + }, + async () => { + if (isUpgrade) { + await events.installation.upgraded(currentVersion, newVersion) + } else if (isDowngrade) { + await events.installation.downgraded(currentVersion, newVersion) + } } - } - ) - await events.identification.identifyInstallationGroup(install.installId) + ) + await events.identification.identifyInstallationGroup(install.installId) + } + } + } catch (err: any) { + if (err?.message?.includes("Invalid Version")) { + logAlert(`Invalid version "${newVersion}" - is it semver?`) + } else { + logAlert("Failed to retrieve version", err) } } } From e0d8362009b5479cdd2b6d67dda79754349ddc92 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 16 Feb 2024 15:57:27 +0000 Subject: [PATCH 056/213] Make a better MySQL healthcheck. --- .../src/integrations/tests/utils/mongodb.ts | 4 +- .../src/integrations/tests/utils/mysql.ts | 39 ++++++++++++------- .../src/integrations/tests/utils/postgres.ts | 4 +- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/packages/server/src/integrations/tests/utils/mongodb.ts b/packages/server/src/integrations/tests/utils/mongodb.ts index ebd76e4baf..0baafc6276 100644 --- a/packages/server/src/integrations/tests/utils/mongodb.ts +++ b/packages/server/src/integrations/tests/utils/mongodb.ts @@ -11,7 +11,9 @@ export async function start(): Promise { MONGO_INITDB_ROOT_PASSWORD: "password", }) .withWaitStrategy( - Wait.forSuccessfulCommand(`mongosh --eval "db.version()"`) + Wait.forSuccessfulCommand( + `mongosh --eval "db.version()"` + ).withStartupTimeout(10000) ) .start() } diff --git a/packages/server/src/integrations/tests/utils/mysql.ts b/packages/server/src/integrations/tests/utils/mysql.ts index 474819287e..8d5563c6dd 100644 --- a/packages/server/src/integrations/tests/utils/mysql.ts +++ b/packages/server/src/integrations/tests/utils/mysql.ts @@ -1,26 +1,37 @@ import { Datasource, SourceName } from "@budibase/types" import { GenericContainer, Wait, StartedTestContainer } from "testcontainers" +import { + AbstractWaitStrategy, + WaitStrategy, +} from "testcontainers/build/wait-strategies/wait-strategy" let container: StartedTestContainer | undefined +class MySQLWaitStrategy extends AbstractWaitStrategy { + async waitUntilReady(container: any, boundPorts: any, startTime?: Date) { + // Because MySQL first starts itself up, runs an init script, then restarts, + // it's possible for the mysqladmin ping to succeed early and then tests to + // run against a MySQL that's mid-restart and fail. To get around this, we + // wait for logs and then do a ping check. + + const logs = Wait.forLogMessage( + "/usr/sbin/mysqld: ready for connections", + 2 + ) + await logs.waitUntilReady(container, boundPorts, startTime) + + const command = Wait.forSuccessfulCommand( + `mysqladmin ping -h localhost -P 3306 -u root -ppassword` + ) + await command.waitUntilReady(container) + } +} + export async function start(): Promise { return await new GenericContainer("mysql:8.3") .withExposedPorts(3306) .withEnvironment({ MYSQL_ROOT_PASSWORD: "password" }) - .withWaitStrategy( - Wait.forSuccessfulCommand( - // Because MySQL first starts itself up, runs an init script, then restarts, - // it's possible for the mysqladmin ping to succeed early and then tests to - // run against a MySQL that's mid-restart and fail. To avoid this, we run - // the ping command three times with a small delay between each. - ` - mysqladmin ping -h localhost -P 3306 -u root -ppassword && sleep 1 && - mysqladmin ping -h localhost -P 3306 -u root -ppassword && sleep 1 && - mysqladmin ping -h localhost -P 3306 -u root -ppassword && sleep 1 && - mysqladmin ping -h localhost -P 3306 -u root -ppassword - ` - ) - ) + .withWaitStrategy(new MySQLWaitStrategy().withStartupTimeout(10000)) .start() } diff --git a/packages/server/src/integrations/tests/utils/postgres.ts b/packages/server/src/integrations/tests/utils/postgres.ts index 4bf42c7f88..82a62e3916 100644 --- a/packages/server/src/integrations/tests/utils/postgres.ts +++ b/packages/server/src/integrations/tests/utils/postgres.ts @@ -8,7 +8,9 @@ export async function start(): Promise { .withExposedPorts(5432) .withEnvironment({ POSTGRES_PASSWORD: "password" }) .withWaitStrategy( - Wait.forSuccessfulCommand("pg_isready -h localhost -p 5432") + Wait.forSuccessfulCommand( + "pg_isready -h localhost -p 5432" + ).withStartupTimeout(10000) ) .start() } From 7211cf4bbf80d563a3b284eaaf6ef25d9594ba89 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 16 Feb 2024 16:11:55 +0000 Subject: [PATCH 057/213] Remove unused import. --- packages/server/src/integrations/tests/utils/mysql.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/server/src/integrations/tests/utils/mysql.ts b/packages/server/src/integrations/tests/utils/mysql.ts index 8d5563c6dd..5e51478998 100644 --- a/packages/server/src/integrations/tests/utils/mysql.ts +++ b/packages/server/src/integrations/tests/utils/mysql.ts @@ -1,9 +1,6 @@ import { Datasource, SourceName } from "@budibase/types" import { GenericContainer, Wait, StartedTestContainer } from "testcontainers" -import { - AbstractWaitStrategy, - WaitStrategy, -} from "testcontainers/build/wait-strategies/wait-strategy" +import { AbstractWaitStrategy } from "testcontainers/build/wait-strategies/wait-strategy" let container: StartedTestContainer | undefined From c12e5fd196a38696a3a8a3f0a778e966caef5b97 Mon Sep 17 00:00:00 2001 From: melohagan <101575380+melohagan@users.noreply.github.com> Date: Mon, 19 Feb 2024 09:13:03 +0000 Subject: [PATCH 058/213] Fix array type missing from query schema selector (#12772) * Tidy MongoDB aggregation pipeline view * Remove unused code * WIP * Add bindings for bindings drawer * Is not external table if it's a query * Add QueryArrayFetch * Bug fix * JavaScript is the worst * refactor * Add array label to query schema * Remove console log * type fix * Don't include Array in SchemaTypeOptions, but show label * Fix bindings * refactor * Rename isObject to hasSchema * WIP * Typing WIP * Type not Types * Unused import * type fix * Handle json array subtype * Support queryarray datasource type * refactor * yarn lock * update account portal --------- Co-authored-by: Sam Rose --- .../src/events/publishers/query.ts | 5 +- .../DataSourceSelect/DataSourceSelect.svelte | 11 +- .../integration/KeyValueBuilder.svelte | 14 +- .../components/integration/QueryViewer.svelte | 5 +- .../src/components/integration/index.svelte | 2 - .../builder/src/constants/backend/index.js | 1 + packages/builder/src/dataBinding.js | 15 ++- .../src/components/app/forms/Form.svelte | 2 +- packages/client/src/utils/schema.js | 2 + .../src/fetch/QueryArrayFetch.js | 25 ++++ packages/frontend-core/src/fetch/index.js | 2 + packages/frontend-core/src/utils/json.js | 32 +++++ .../server/src/api/controllers/query/index.ts | 126 +++++++++++------- packages/shared-core/src/utils.ts | 10 ++ packages/types/src/documents/app/query.ts | 13 ++ .../src/documents/app/table/constants.ts | 4 + .../types/src/documents/app/table/schema.ts | 7 + yarn.lock | 8 +- 18 files changed, 219 insertions(+), 65 deletions(-) create mode 100644 packages/frontend-core/src/fetch/QueryArrayFetch.js diff --git a/packages/backend-core/src/events/publishers/query.ts b/packages/backend-core/src/events/publishers/query.ts index 7d28129cf6..48603257d2 100644 --- a/packages/backend-core/src/events/publishers/query.ts +++ b/packages/backend-core/src/events/publishers/query.ts @@ -3,6 +3,7 @@ import { Event, Datasource, Query, + QueryPreview, QueryCreatedEvent, QueryUpdatedEvent, QueryDeletedEvent, @@ -68,9 +69,9 @@ const run = async (count: number, timestamp?: string | number) => { await publishEvent(Event.QUERIES_RUN, properties, timestamp) } -const previewed = async (datasource: Datasource, query: Query) => { +const previewed = async (datasource: Datasource, query: QueryPreview) => { const properties: QueryPreviewedEvent = { - queryId: query._id, + queryId: query.queryId, datasourceId: datasource._id as string, source: datasource.source, queryVerb: query.queryVerb, diff --git a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte index 14cbc973a1..0e01c264fc 100644 --- a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte @@ -127,10 +127,14 @@ } }) $: jsonArrays = bindings - .filter(x => x.fieldSchema?.type === "jsonarray") + .filter( + x => + x.fieldSchema?.type === "jsonarray" || + (x.fieldSchema?.type === "json" && x.fieldSchema?.subtype === "array") + ) .map(binding => { const { providerId, readableBinding, runtimeBinding, tableId } = binding - const { name, type, prefixKeys } = binding.fieldSchema + const { name, type, prefixKeys, subtype } = binding.fieldSchema return { providerId, label: readableBinding, @@ -138,7 +142,8 @@ fieldType: type, tableId, prefixKeys, - type: "jsonarray", + type: type === "jsonarray" ? "jsonarray" : "queryarray", + subtype, value: `{{ literal ${runtimeBinding} }}`, } }) diff --git a/packages/builder/src/components/integration/KeyValueBuilder.svelte b/packages/builder/src/components/integration/KeyValueBuilder.svelte index 8dac07bcec..e71090f613 100644 --- a/packages/builder/src/components/integration/KeyValueBuilder.svelte +++ b/packages/builder/src/components/integration/KeyValueBuilder.svelte @@ -85,6 +85,16 @@ activity = newActivity dispatch("change", fields) } + + function isJsonArray(value) { + if (!value || typeof value === "string") { + return false + } + if (value.type === "array") { + return true + } + return value.type === "json" && value.subtype === "array" + } @@ -112,7 +122,9 @@ bind:value={field.name} on:blur={changed} /> - {#if options} + {#if isJsonArray(field.value)} +
-
Stage {index + 1} diff --git a/packages/builder/src/constants/backend/index.js b/packages/builder/src/constants/backend/index.js index eb47ac97fe..f1e3e1e2c2 100644 --- a/packages/builder/src/constants/backend/index.js +++ b/packages/builder/src/constants/backend/index.js @@ -310,6 +310,7 @@ export const BannedSearchTypes = [ "formula", "json", "jsonarray", + "queryarray", ] export const DatasourceTypes = { diff --git a/packages/builder/src/dataBinding.js b/packages/builder/src/dataBinding.js index 8c71631b09..0442a67da9 100644 --- a/packages/builder/src/dataBinding.js +++ b/packages/builder/src/dataBinding.js @@ -425,7 +425,7 @@ const generateComponentContextBindings = (asset, componentContext) => { table = info.table // Determine what to prefix bindings with - if (datasource.type === "jsonarray") { + if (datasource.type === "jsonarray" || datasource.type === "queryarray") { // For JSON arrays, use the array name as the readable prefix const split = datasource.label.split(".") readablePrefix = split[split.length - 1] @@ -904,6 +904,19 @@ export const getSchemaForDatasource = (asset, datasource, options) => { schema = JSONUtils.getJSONArrayDatasourceSchema(tableSchema, datasource) } + // "queryarray" datasources are arrays inside JSON responses + else if (type === "queryarray") { + const queries = get(queriesStores).list + table = queries.find(query => query._id === datasource.tableId) + let tableSchema = table?.schema + let nestedSchemaFields = table?.nestedSchemaFields + schema = JSONUtils.generateQueryArraySchemas( + tableSchema, + nestedSchemaFields + ) + schema = JSONUtils.getJSONArrayDatasourceSchema(schema, datasource) + } + // Otherwise we assume we're targeting an internal table or a plus // datasource, and we can treat it as a table with a schema else { diff --git a/packages/client/src/components/app/forms/Form.svelte b/packages/client/src/components/app/forms/Form.svelte index 464ca95829..5522bd4b46 100644 --- a/packages/client/src/components/app/forms/Form.svelte +++ b/packages/client/src/components/app/forms/Form.svelte @@ -84,7 +84,7 @@ // Fetches the form schema from this form's dataSource const fetchSchema = async dataSource => { - if (dataSource?.tableId && dataSource?.type !== "query") { + if (dataSource?.tableId && !dataSource?.type?.startsWith("query")) { try { table = await API.fetchTableDefinition(dataSource.tableId) } catch (error) { diff --git a/packages/client/src/utils/schema.js b/packages/client/src/utils/schema.js index f20e724a6e..e2399e8738 100644 --- a/packages/client/src/utils/schema.js +++ b/packages/client/src/utils/schema.js @@ -7,6 +7,7 @@ import NestedProviderFetch from "@budibase/frontend-core/src/fetch/NestedProvide import FieldFetch from "@budibase/frontend-core/src/fetch/FieldFetch.js" import JSONArrayFetch from "@budibase/frontend-core/src/fetch/JSONArrayFetch.js" import ViewV2Fetch from "@budibase/frontend-core/src/fetch/ViewV2Fetch.js" +import QueryArrayFetch from "@budibase/frontend-core/src/fetch/QueryArrayFetch" /** * Fetches the schema of any kind of datasource. @@ -28,6 +29,7 @@ export const fetchDatasourceSchema = async ( provider: NestedProviderFetch, field: FieldFetch, jsonarray: JSONArrayFetch, + queryarray: QueryArrayFetch, }[datasource?.type] if (!handler) { return null diff --git a/packages/frontend-core/src/fetch/QueryArrayFetch.js b/packages/frontend-core/src/fetch/QueryArrayFetch.js new file mode 100644 index 0000000000..0b36b640a6 --- /dev/null +++ b/packages/frontend-core/src/fetch/QueryArrayFetch.js @@ -0,0 +1,25 @@ +import FieldFetch from "./FieldFetch.js" +import { + getJSONArrayDatasourceSchema, + generateQueryArraySchemas, +} from "../utils/json" + +export default class QueryArrayFetch extends FieldFetch { + async getDefinition(datasource) { + if (!datasource?.tableId) { + return null + } + // JSON arrays need their table definitions fetched. + // We can then extract their schema as a subset of the table schema. + try { + const table = await this.API.fetchQueryDefinition(datasource.tableId) + const schema = generateQueryArraySchemas( + table?.schema, + table?.nestedSchemaFields + ) + return { schema: getJSONArrayDatasourceSchema(schema, datasource) } + } catch (error) { + return null + } + } +} diff --git a/packages/frontend-core/src/fetch/index.js b/packages/frontend-core/src/fetch/index.js index a41a859351..903810ac25 100644 --- a/packages/frontend-core/src/fetch/index.js +++ b/packages/frontend-core/src/fetch/index.js @@ -9,6 +9,7 @@ import JSONArrayFetch from "./JSONArrayFetch.js" import UserFetch from "./UserFetch.js" import GroupUserFetch from "./GroupUserFetch.js" import CustomFetch from "./CustomFetch.js" +import QueryArrayFetch from "./QueryArrayFetch.js" const DataFetchMap = { table: TableFetch, @@ -24,6 +25,7 @@ const DataFetchMap = { provider: NestedProviderFetch, field: FieldFetch, jsonarray: JSONArrayFetch, + queryarray: QueryArrayFetch, } // Constructs a new fetch model for a certain datasource diff --git a/packages/frontend-core/src/utils/json.js b/packages/frontend-core/src/utils/json.js index 29bf2df34e..8cd37f9ad1 100644 --- a/packages/frontend-core/src/utils/json.js +++ b/packages/frontend-core/src/utils/json.js @@ -1,3 +1,5 @@ +import { utils } from "@budibase/shared-core" + /** * Gets the schema for a datasource which is targeting a JSON array, including * nested JSON arrays. The returned schema is a squashed, table-like schema @@ -119,3 +121,33 @@ const extractJSONSchemaKeys = (jsonSchema, squashObjects = false) => { }) return keys } + +export const generateQueryArraySchemas = (schema, nestedSchemaFields) => { + for (let key in schema) { + if ( + schema[key]?.type === "json" && + schema[key]?.subtype === "array" && + utils.hasSchema(nestedSchemaFields[key]) + ) { + schema[key] = { + schema: { + schema: Object.entries(nestedSchemaFields[key] || {}).reduce( + (acc, [nestedKey, fieldSchema]) => { + acc[nestedKey] = { + name: nestedKey, + type: fieldSchema.type, + subtype: fieldSchema.subtype, + } + return acc + }, + {} + ), + type: "json", + }, + type: "json", + subtype: "array", + } + } + } + return schema +} diff --git a/packages/server/src/api/controllers/query/index.ts b/packages/server/src/api/controllers/query/index.ts index 8dabe5b3cc..89330f3216 100644 --- a/packages/server/src/api/controllers/query/index.ts +++ b/packages/server/src/api/controllers/query/index.ts @@ -1,5 +1,4 @@ import { generateQueryID } from "../../../db/utils" -import { BaseQueryVerbs } from "../../../constants" import { Thread, ThreadType } from "../../../threads" import { save as saveDatasource } from "../datasource" import { RestImporter } from "./import" @@ -7,36 +6,27 @@ import { invalidateDynamicVariables } from "../../../threads/utils" import env from "../../../environment" import { events, context, utils, constants } from "@budibase/backend-core" import sdk from "../../../sdk" -import { QueryEvent, QueryResponse } from "../../../threads/definitions" +import { QueryEvent } from "../../../threads/definitions" import { ConfigType, Query, UserCtx, SessionCookie, + JsonFieldSubType, + QueryResponse, + QueryPreview, QuerySchema, FieldType, type ExecuteQueryRequest, type ExecuteQueryResponse, type Row, } from "@budibase/types" -import { ValidQueryNameRegex } from "@budibase/shared-core" +import { ValidQueryNameRegex, utils as JsonUtils } from "@budibase/shared-core" const Runner = new Thread(ThreadType.QUERY, { timeoutMs: env.QUERY_THREAD_TIMEOUT, }) -// simple function to append "readable" to all read queries -function enrichQueries(input: any) { - const wasArray = Array.isArray(input) - const queries = wasArray ? input : [input] - for (let query of queries) { - if (query.queryVerb === BaseQueryVerbs.READ) { - query.readable = true - } - } - return wasArray ? queries : queries[0] -} - export async function fetch(ctx: UserCtx) { ctx.body = await sdk.queries.fetch() } @@ -84,7 +74,7 @@ export { _import as import } export async function save(ctx: UserCtx) { const db = context.getAppDB() - const query = ctx.request.body + const query: Query = ctx.request.body // Validate query name if (!query?.name.match(ValidQueryNameRegex)) { @@ -100,7 +90,6 @@ export async function save(ctx: UserCtx) { } else { eventFn = () => events.query.updated(datasource, query) } - const response = await db.put(query) await eventFn() query._rev = response.rev @@ -133,7 +122,7 @@ export async function preview(ctx: UserCtx) { const { datasource, envVars } = await sdk.datasources.getWithEnvVars( ctx.request.body.datasourceId ) - const query = ctx.request.body + const query: QueryPreview = ctx.request.body // preview may not have a queryId as it hasn't been saved, but if it does // this stops dynamic variables from calling the same query const { fields, parameters, queryVerb, transformer, queryId, schema } = query @@ -153,6 +142,69 @@ export async function preview(ctx: UserCtx) { const authConfigCtx: any = getAuthConfig(ctx) + function getSchemaFields( + rows: any[], + keys: string[] + ): { + previewSchema: Record + nestedSchemaFields: { + [key: string]: Record + } + } { + const previewSchema: Record = {} + const nestedSchemaFields: { + [key: string]: Record + } = {} + const makeQuerySchema = ( + type: FieldType, + name: string, + subtype?: string + ): QuerySchema => ({ + type, + name, + subtype, + }) + if (rows?.length > 0) { + for (let key of [...new Set(keys)] as string[]) { + const field = rows[0][key] + let type = typeof field, + fieldMetadata = makeQuerySchema(FieldType.STRING, key) + if (field) + switch (type) { + case "boolean": + fieldMetadata = makeQuerySchema(FieldType.BOOLEAN, key) + break + case "object": + if (field instanceof Date) { + fieldMetadata = makeQuerySchema(FieldType.DATETIME, key) + } else if (Array.isArray(field)) { + if (JsonUtils.hasSchema(field[0])) { + fieldMetadata = makeQuerySchema( + FieldType.JSON, + key, + JsonFieldSubType.ARRAY + ) + } else { + fieldMetadata = makeQuerySchema(FieldType.ARRAY, key) + } + nestedSchemaFields[key] = getSchemaFields( + field, + Object.keys(field[0]) + ).previewSchema + } else { + fieldMetadata = makeQuerySchema(FieldType.JSON, key) + } + break + case "number": + fieldMetadata = makeQuerySchema(FieldType.NUMBER, key) + break + } + previewSchema[key] = fieldMetadata + } + } + return { previewSchema, nestedSchemaFields } + } + try { const inputs: QueryEvent = { appId: ctx.appId, @@ -171,38 +223,11 @@ export async function preview(ctx: UserCtx) { }, } - const { rows, keys, info, extra } = await Runner.run(inputs) - const previewSchema: Record = {} - const makeQuerySchema = (type: FieldType, name: string): QuerySchema => ({ - type, - name, - }) - if (rows?.length > 0) { - for (let key of [...new Set(keys)] as string[]) { - const field = rows[0][key] - let type = typeof field, - fieldMetadata = makeQuerySchema(FieldType.STRING, key) - if (field) - switch (type) { - case "boolean": - fieldMetadata = makeQuerySchema(FieldType.BOOLEAN, key) - break - case "object": - if (field instanceof Date) { - fieldMetadata = makeQuerySchema(FieldType.DATETIME, key) - } else if (Array.isArray(field)) { - fieldMetadata = makeQuerySchema(FieldType.ARRAY, key) - } else { - fieldMetadata = makeQuerySchema(FieldType.JSON, key) - } - break - case "number": - fieldMetadata = makeQuerySchema(FieldType.NUMBER, key) - break - } - previewSchema[key] = fieldMetadata - } - } + const { rows, keys, info, extra } = (await Runner.run( + inputs + )) as QueryResponse + const { previewSchema, nestedSchemaFields } = getSchemaFields(rows, keys) + // if existing schema, update to include any previous schema keys if (existingSchema) { for (let key of Object.keys(previewSchema)) { @@ -216,6 +241,7 @@ export async function preview(ctx: UserCtx) { await events.query.previewed(datasource, query) ctx.body = { rows, + nestedSchemaFields, schema: previewSchema, info, extra, diff --git a/packages/shared-core/src/utils.ts b/packages/shared-core/src/utils.ts index c775010909..cc5646a00e 100644 --- a/packages/shared-core/src/utils.ts +++ b/packages/shared-core/src/utils.ts @@ -57,3 +57,13 @@ export function filterValueToLabel() { {} ) } + +export function hasSchema(test: any) { + return ( + typeof test === "object" && + !Array.isArray(test) && + test !== null && + !(test instanceof Date) && + Object.keys(test).length > 0 + ) +} diff --git a/packages/types/src/documents/app/query.ts b/packages/types/src/documents/app/query.ts index 81aa90b807..f4547b9774 100644 --- a/packages/types/src/documents/app/query.ts +++ b/packages/types/src/documents/app/query.ts @@ -4,6 +4,7 @@ import type { Row } from "./row" export interface QuerySchema { name?: string type: string + subtype?: string } export interface Query extends Document { @@ -17,11 +18,23 @@ export interface Query extends Document { queryVerb: string } +export interface QueryPreview extends Omit { + queryId: string +} + export interface QueryParameter { name: string default: string } +export interface QueryResponse { + rows: any[] + keys: string[] + info: any + extra: any + pagination: any +} + export interface RestQueryFields { path: string queryString?: string diff --git a/packages/types/src/documents/app/table/constants.ts b/packages/types/src/documents/app/table/constants.ts index fc831e7e7c..1d9d14695a 100644 --- a/packages/types/src/documents/app/table/constants.ts +++ b/packages/types/src/documents/app/table/constants.ts @@ -16,6 +16,10 @@ export enum AutoFieldSubType { AUTO_ID = "autoID", } +export enum JsonFieldSubType { + ARRAY = "array", +} + export enum FormulaType { STATIC = "static", DYNAMIC = "dynamic", diff --git a/packages/types/src/documents/app/table/schema.ts b/packages/types/src/documents/app/table/schema.ts index 47ec303b66..17abf747b2 100644 --- a/packages/types/src/documents/app/table/schema.ts +++ b/packages/types/src/documents/app/table/schema.ts @@ -5,6 +5,7 @@ import { AutoFieldSubType, AutoReason, FormulaType, + JsonFieldSubType, RelationshipType, } from "./constants" @@ -81,6 +82,11 @@ export interface NumberFieldMetadata extends Omit { } } +export interface JsonFieldMetadata extends Omit { + type: FieldType.JSON + subtype?: JsonFieldSubType.ARRAY +} + export interface DateFieldMetadata extends Omit { type: FieldType.DATETIME ignoreTimezones?: boolean @@ -162,6 +168,7 @@ export type FieldSchema = | NumberFieldMetadata | LongFormFieldMetadata | BBReferenceFieldMetadata + | JsonFieldMetadata export interface TableSchema { [key: string]: FieldSchema diff --git a/yarn.lock b/yarn.lock index 1937482837..c0a11b9bf7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5572,9 +5572,9 @@ integrity sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg== "@types/node@^18.11.18": - version "18.19.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.10.tgz#4de314ab66faf6bc8ba691021a091ddcdf13a158" - integrity sha512-IZD8kAM02AW1HRDTPOlz3npFava678pr8Ie9Vp8uRhBROXAv8MXT2pCnGZZAKYdromsNQLHQcfWQ6EOatVLtqA== + version "18.19.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.13.tgz#c3e989ca967b862a1f6c8c4148fe31865eedaf1a" + integrity sha512-kgnbRDj8ioDyGxoiaXsiu1Ybm/K14ajCgMOkwiqpHrnF7d7QiYRoRqHIpglMMs3DwXinlK4qJ8TZGlj4hfleJg== dependencies: undici-types "~5.26.4" @@ -10763,7 +10763,7 @@ fetch-cookie@0.11.0: dependencies: tough-cookie "^2.3.3 || ^3.0.1 || ^4.0.0" -fflate@^0.4.1: +fflate@^0.4.1, fflate@^0.4.8: version "0.4.8" resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae" integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA== From b1966114ef77f2a351a982f38ac1e5abaea276af Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Mon, 19 Feb 2024 09:28:34 +0000 Subject: [PATCH 059/213] Bump version to 2.19.6 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 596fb434bc..62068e25a8 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.19.5", + "version": "2.19.6", "npmClient": "yarn", "packages": [ "packages/*", From 4f05bc619b4c2cd8627b965326389bfaee6bf199 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 19 Feb 2024 09:51:10 +0000 Subject: [PATCH 060/213] Handle branding cookies with different tenant ids --- .../builder/src/pages/builder/auth/_layout.svelte | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/pages/builder/auth/_layout.svelte b/packages/builder/src/pages/builder/auth/_layout.svelte index f5484182e8..8902e9ac61 100644 --- a/packages/builder/src/pages/builder/auth/_layout.svelte +++ b/packages/builder/src/pages/builder/auth/_layout.svelte @@ -10,13 +10,18 @@ $redirect("../") } - if ($admin?.checklist?.branding) { + if ($admin.cloud && $admin?.checklist?.branding) { let url = new URL(window.location.href) let hostname = url.hostname let parts = hostname.split(".") - let tenantId = parts[0] + let newTenantId = parts[0] let domain = parts.slice(-2).join(".") - CookieUtils.setCookie("tenantId", tenantId, domain) + + let existingTenantId = CookieUtils.getCookie("tenantId") + + if (!existingTenantId || existingTenantId !== newTenantId) { + CookieUtils.setCookie("tenantId", newTenantId, domain) + } } if ( From b563fb48c8485733176806c7a76291f13062f96c Mon Sep 17 00:00:00 2001 From: melohagan <101575380+melohagan@users.noreply.github.com> Date: Mon, 19 Feb 2024 11:09:36 +0000 Subject: [PATCH 061/213] Error when deleting selected rows that have attachment (#13063) * Deprecate selectedRowIds * Delete selected rows table * Add selectedRows to table block context * update account-portal * update account-portal * Lowercase deprecated * Make sure attachment fields are empty arrays not null * unit test --- packages/server/src/utilities/rowProcessor/attachments.ts | 3 +++ .../src/utilities/rowProcessor/tests/attachments.spec.ts | 8 ++++++++ yarn.lock | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/server/src/utilities/rowProcessor/attachments.ts b/packages/server/src/utilities/rowProcessor/attachments.ts index 799eab1d3a..c289680eb3 100644 --- a/packages/server/src/utilities/rowProcessor/attachments.ts +++ b/packages/server/src/utilities/rowProcessor/attachments.ts @@ -72,6 +72,9 @@ export class AttachmentCleanup { continue } rows.forEach(row => { + if (!Array.isArray(row[key])) { + return + } files = files.concat( row[key].map((attachment: any) => attachment.key) ) diff --git a/packages/server/src/utilities/rowProcessor/tests/attachments.spec.ts b/packages/server/src/utilities/rowProcessor/tests/attachments.spec.ts index 762ec3bb8c..43af79d82c 100644 --- a/packages/server/src/utilities/rowProcessor/tests/attachments.spec.ts +++ b/packages/server/src/utilities/rowProcessor/tests/attachments.spec.ts @@ -103,6 +103,14 @@ describe("attachment cleanup", () => { expect(mockedDeleteFiles).toBeCalledWith(BUCKET, [FILE_NAME]) }) + it("should handle row deletion and not throw when attachments are undefined", async () => { + await AttachmentCleanup.rowDelete(table(), [ + { + attach: undefined, + }, + ]) + }) + it("shouldn't cleanup attachments if row not updated", async () => { await AttachmentCleanup.rowUpdate(table(), { row: row(), oldRow: row() }) expect(mockedDeleteFiles).not.toBeCalled() diff --git a/yarn.lock b/yarn.lock index c0a11b9bf7..10acc829b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10763,7 +10763,7 @@ fetch-cookie@0.11.0: dependencies: tough-cookie "^2.3.3 || ^3.0.1 || ^4.0.0" -fflate@^0.4.1, fflate@^0.4.8: +fflate@^0.4.1: version "0.4.8" resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae" integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA== From 04b7fda08b63a5c7d120154240b82c4f4ab9cc8c Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 15:47:52 +0100 Subject: [PATCH 062/213] Move vm code --- packages/server/src/jsRunner/vm/builtin-vm.ts | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 packages/server/src/jsRunner/vm/builtin-vm.ts diff --git a/packages/server/src/jsRunner/vm/builtin-vm.ts b/packages/server/src/jsRunner/vm/builtin-vm.ts new file mode 100644 index 0000000000..c439603acd --- /dev/null +++ b/packages/server/src/jsRunner/vm/builtin-vm.ts @@ -0,0 +1,75 @@ +import vm from "vm" +import env from "../../environment" +import { setOnErrorLog } from "@budibase/string-templates" +import { context, logging, timers } from "@budibase/backend-core" +import tracer from "dd-trace" +import { serializeError } from "serialize-error" +import { VM } from "@budibase/types" + +type TrackerFn = (f: () => T) => T + +export class BuiltInVM implements VM { + private ctx: vm.Context + + constructor(ctx: vm.Context) { + this.ctx = ctx + + if (env.LOG_JS_ERRORS) { + setOnErrorLog((error: Error) => { + logging.logWarn(JSON.stringify(serializeError(error))) + }) + } + } + + execute(code: string) { + return tracer.trace("runJS", {}, span => { + const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS + let track: TrackerFn = f => f() + if (perRequestLimit) { + const bbCtx = tracer.trace("runJS.getCurrentContext", {}, span => + context.getCurrentContext() + ) + if (bbCtx) { + if (!bbCtx.jsExecutionTracker) { + span?.addTags({ + createdExecutionTracker: true, + }) + bbCtx.jsExecutionTracker = tracer.trace( + "runJS.createExecutionTimeTracker", + {}, + span => timers.ExecutionTimeTracker.withLimit(perRequestLimit) + ) + } + span?.addTags({ + js: { + limitMS: bbCtx.jsExecutionTracker.limitMs, + elapsedMS: bbCtx.jsExecutionTracker.elapsedMS, + }, + }) + // We call checkLimit() here to prevent paying the cost of creating + // a new VM context below when we don't need to. + tracer.trace("runJS.checkLimitAndBind", {}, span => { + bbCtx.jsExecutionTracker!.checkLimit() + track = bbCtx.jsExecutionTracker!.track.bind( + bbCtx.jsExecutionTracker + ) + }) + } + } + + this.ctx = { + ...this.ctx, + alert: undefined, + setInterval: undefined, + setTimeout: undefined, + } + + vm.createContext(this.ctx) + return track(() => + vm.runInNewContext(code, this.ctx, { + timeout: env.JS_PER_INVOCATION_TIMEOUT_MS, + }) + ) + }) + } +} From a84474bd62032e67c74acf2bc0162c710c949da3 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 15:49:38 +0100 Subject: [PATCH 063/213] Export --- packages/server/src/jsRunner/vm/index.ts | 272 +----------------- .../server/src/jsRunner/vm/isolated-vm.ts | 270 +++++++++++++++++ 2 files changed, 272 insertions(+), 270 deletions(-) create mode 100644 packages/server/src/jsRunner/vm/isolated-vm.ts diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index ab26f3f6d1..cc50a5eeaa 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -1,270 +1,2 @@ -import ivm from "isolated-vm" -import bson from "bson" - -import url from "url" -import crypto from "crypto" -import querystring from "querystring" - -import { BundleType, loadBundle } from "../bundles" -import { VM } from "@budibase/types" - -class ExecutionTimeoutError extends Error { - constructor(message: string) { - super(message) - this.name = "ExecutionTimeoutError" - } -} - -class ModuleHandler { - private modules: { - import: string - moduleKey: string - module: ivm.Module - }[] = [] - - private generateRandomKey = () => `i${crypto.randomUUID().replace(/-/g, "")}` - - registerModule(module: ivm.Module, imports: string) { - this.modules.push({ - moduleKey: this.generateRandomKey(), - import: imports, - module: module, - }) - } - - generateImports() { - return this.modules - .map(m => `import ${m.import} from "${m.moduleKey}"`) - .join(";") - } - - getModule(key: string) { - const module = this.modules.find(m => m.moduleKey === key) - return module?.module - } -} - -export class IsolatedVM implements VM { - private isolate: ivm.Isolate - private vm: ivm.Context - private jail: ivm.Reference - private invocationTimeout: number - private isolateAccumulatedTimeout?: number - - // By default the wrapper returns itself - private codeWrapper: (code: string) => string = code => code - - private moduleHandler = new ModuleHandler() - - private readonly resultKey = "results" - - constructor({ - memoryLimit, - invocationTimeout, - isolateAccumulatedTimeout, - }: { - memoryLimit: number - invocationTimeout: number - isolateAccumulatedTimeout?: number - }) { - this.isolate = new ivm.Isolate({ memoryLimit }) - this.vm = this.isolate.createContextSync() - this.jail = this.vm.global - this.jail.setSync("global", this.jail.derefInto()) - - this.addToContext({ - [this.resultKey]: { out: "" }, - }) - - this.invocationTimeout = invocationTimeout - this.isolateAccumulatedTimeout = isolateAccumulatedTimeout - } - - withHelpers() { - const urlModule = this.registerCallbacks({ - resolve: url.resolve, - parse: url.parse, - }) - - const querystringModule = this.registerCallbacks({ - escape: querystring.escape, - }) - - this.addToContext({ - helpersStripProtocol: new ivm.Callback((str: string) => { - var parsed = url.parse(str) as any - parsed.protocol = "" - return parsed.format() - }), - }) - - const injectedRequire = `const require=function req(val) { - switch (val) { - case "url": return ${urlModule}; - case "querystring": return ${querystringModule}; - } - }` - const helpersSource = loadBundle(BundleType.HELPERS) - const helpersModule = this.isolate.compileModuleSync( - `${injectedRequire};${helpersSource}` - ) - - helpersModule.instantiateSync(this.vm, specifier => { - if (specifier === "crypto") { - const cryptoModule = this.registerCallbacks({ - randomUUID: crypto.randomUUID, - }) - const module = this.isolate.compileModuleSync( - `export default ${cryptoModule}` - ) - module.instantiateSync(this.vm, specifier => { - throw new Error(`No imports allowed. Required: ${specifier}`) - }) - return module - } - throw new Error(`No imports allowed. Required: ${specifier}`) - }) - - this.moduleHandler.registerModule(helpersModule, "helpers") - return this - } - - withContext(context: Record) { - this.addToContext(context) - - return this - } - - withParsingBson(data: any) { - this.addToContext({ - bsonData: bson.BSON.serialize({ data }), - }) - - // If we need to parse bson, we follow the next steps: - // 1. Serialise the data from potential BSON to buffer before passing it to the isolate - // 2. Deserialise the data within the isolate, to get the original data - // 3. Process script - // 4. Stringify the result in order to convert the result from BSON to json - this.codeWrapper = code => - `(function(){ - const data = deserialize(bsonData, { validation: { utf8: false } }).data; - const result = ${code} - return toJson(result); - })();` - - const bsonSource = loadBundle(BundleType.BSON) - - this.addToContext({ - textDecoderCb: new ivm.Callback( - (args: { - constructorArgs: any - functionArgs: Parameters["decode"]> - }) => { - const result = new TextDecoder(...args.constructorArgs).decode( - ...args.functionArgs - ) - return result - } - ), - }) - - // "Polyfilling" text decoder. `bson.deserialize` requires decoding. We are creating a bridge function so we don't need to inject the full library - const textDecoderPolyfill = class TextDecoder { - constructorArgs - - constructor(...constructorArgs: any) { - this.constructorArgs = constructorArgs - } - - decode(...input: any) { - // @ts-ignore - return textDecoderCb({ - constructorArgs: this.constructorArgs, - functionArgs: input, - }) - } - }.toString() - const bsonModule = this.isolate.compileModuleSync( - `${textDecoderPolyfill};${bsonSource}` - ) - bsonModule.instantiateSync(this.vm, specifier => { - throw new Error(`No imports allowed. Required: ${specifier}`) - }) - - this.moduleHandler.registerModule(bsonModule, "{deserialize, toJson}") - - return this - } - - execute(code: string): any { - if (this.isolateAccumulatedTimeout) { - const cpuMs = Number(this.isolate.cpuTime) / 1e6 - if (cpuMs > this.isolateAccumulatedTimeout) { - throw new ExecutionTimeoutError( - `CPU time limit exceeded (${cpuMs}ms > ${this.isolateAccumulatedTimeout}ms)` - ) - } - } - - code = `${this.moduleHandler.generateImports()};results.out=${this.codeWrapper( - code - )};` - - const script = this.isolate.compileModuleSync(code) - - script.instantiateSync(this.vm, specifier => { - const module = this.moduleHandler.getModule(specifier) - if (module) { - return module - } - - throw new Error(`"${specifier}" import not allowed`) - }) - - script.evaluateSync({ timeout: this.invocationTimeout }) - - const result = this.getFromContext(this.resultKey) - return result.out - } - - private registerCallbacks(functions: Record) { - const libId = crypto.randomUUID().replace(/-/g, "") - - const x: Record = {} - for (const [funcName, func] of Object.entries(functions)) { - const key = `f${libId}${funcName}cb` - x[funcName] = key - - this.addToContext({ - [key]: new ivm.Callback((...params: any[]) => (func as any)(...params)), - }) - } - - const mod = - `{` + - Object.entries(x) - .map(([key, func]) => `${key}: ${func}`) - .join() + - "}" - return mod - } - - private addToContext(context: Record) { - for (let key in context) { - const value = context[key] - this.jail.setSync( - key, - typeof value === "function" - ? value - : new ivm.ExternalCopy(value).copyInto({ release: true }) - ) - } - } - - private getFromContext(key: string) { - const ref = this.vm.global.getSync(key, { reference: true }) - const result = ref.copySync() - ref.release() - return result - } -} +export * from "./isolated-vm" +export * from "./builtin-vm" diff --git a/packages/server/src/jsRunner/vm/isolated-vm.ts b/packages/server/src/jsRunner/vm/isolated-vm.ts new file mode 100644 index 0000000000..ab26f3f6d1 --- /dev/null +++ b/packages/server/src/jsRunner/vm/isolated-vm.ts @@ -0,0 +1,270 @@ +import ivm from "isolated-vm" +import bson from "bson" + +import url from "url" +import crypto from "crypto" +import querystring from "querystring" + +import { BundleType, loadBundle } from "../bundles" +import { VM } from "@budibase/types" + +class ExecutionTimeoutError extends Error { + constructor(message: string) { + super(message) + this.name = "ExecutionTimeoutError" + } +} + +class ModuleHandler { + private modules: { + import: string + moduleKey: string + module: ivm.Module + }[] = [] + + private generateRandomKey = () => `i${crypto.randomUUID().replace(/-/g, "")}` + + registerModule(module: ivm.Module, imports: string) { + this.modules.push({ + moduleKey: this.generateRandomKey(), + import: imports, + module: module, + }) + } + + generateImports() { + return this.modules + .map(m => `import ${m.import} from "${m.moduleKey}"`) + .join(";") + } + + getModule(key: string) { + const module = this.modules.find(m => m.moduleKey === key) + return module?.module + } +} + +export class IsolatedVM implements VM { + private isolate: ivm.Isolate + private vm: ivm.Context + private jail: ivm.Reference + private invocationTimeout: number + private isolateAccumulatedTimeout?: number + + // By default the wrapper returns itself + private codeWrapper: (code: string) => string = code => code + + private moduleHandler = new ModuleHandler() + + private readonly resultKey = "results" + + constructor({ + memoryLimit, + invocationTimeout, + isolateAccumulatedTimeout, + }: { + memoryLimit: number + invocationTimeout: number + isolateAccumulatedTimeout?: number + }) { + this.isolate = new ivm.Isolate({ memoryLimit }) + this.vm = this.isolate.createContextSync() + this.jail = this.vm.global + this.jail.setSync("global", this.jail.derefInto()) + + this.addToContext({ + [this.resultKey]: { out: "" }, + }) + + this.invocationTimeout = invocationTimeout + this.isolateAccumulatedTimeout = isolateAccumulatedTimeout + } + + withHelpers() { + const urlModule = this.registerCallbacks({ + resolve: url.resolve, + parse: url.parse, + }) + + const querystringModule = this.registerCallbacks({ + escape: querystring.escape, + }) + + this.addToContext({ + helpersStripProtocol: new ivm.Callback((str: string) => { + var parsed = url.parse(str) as any + parsed.protocol = "" + return parsed.format() + }), + }) + + const injectedRequire = `const require=function req(val) { + switch (val) { + case "url": return ${urlModule}; + case "querystring": return ${querystringModule}; + } + }` + const helpersSource = loadBundle(BundleType.HELPERS) + const helpersModule = this.isolate.compileModuleSync( + `${injectedRequire};${helpersSource}` + ) + + helpersModule.instantiateSync(this.vm, specifier => { + if (specifier === "crypto") { + const cryptoModule = this.registerCallbacks({ + randomUUID: crypto.randomUUID, + }) + const module = this.isolate.compileModuleSync( + `export default ${cryptoModule}` + ) + module.instantiateSync(this.vm, specifier => { + throw new Error(`No imports allowed. Required: ${specifier}`) + }) + return module + } + throw new Error(`No imports allowed. Required: ${specifier}`) + }) + + this.moduleHandler.registerModule(helpersModule, "helpers") + return this + } + + withContext(context: Record) { + this.addToContext(context) + + return this + } + + withParsingBson(data: any) { + this.addToContext({ + bsonData: bson.BSON.serialize({ data }), + }) + + // If we need to parse bson, we follow the next steps: + // 1. Serialise the data from potential BSON to buffer before passing it to the isolate + // 2. Deserialise the data within the isolate, to get the original data + // 3. Process script + // 4. Stringify the result in order to convert the result from BSON to json + this.codeWrapper = code => + `(function(){ + const data = deserialize(bsonData, { validation: { utf8: false } }).data; + const result = ${code} + return toJson(result); + })();` + + const bsonSource = loadBundle(BundleType.BSON) + + this.addToContext({ + textDecoderCb: new ivm.Callback( + (args: { + constructorArgs: any + functionArgs: Parameters["decode"]> + }) => { + const result = new TextDecoder(...args.constructorArgs).decode( + ...args.functionArgs + ) + return result + } + ), + }) + + // "Polyfilling" text decoder. `bson.deserialize` requires decoding. We are creating a bridge function so we don't need to inject the full library + const textDecoderPolyfill = class TextDecoder { + constructorArgs + + constructor(...constructorArgs: any) { + this.constructorArgs = constructorArgs + } + + decode(...input: any) { + // @ts-ignore + return textDecoderCb({ + constructorArgs: this.constructorArgs, + functionArgs: input, + }) + } + }.toString() + const bsonModule = this.isolate.compileModuleSync( + `${textDecoderPolyfill};${bsonSource}` + ) + bsonModule.instantiateSync(this.vm, specifier => { + throw new Error(`No imports allowed. Required: ${specifier}`) + }) + + this.moduleHandler.registerModule(bsonModule, "{deserialize, toJson}") + + return this + } + + execute(code: string): any { + if (this.isolateAccumulatedTimeout) { + const cpuMs = Number(this.isolate.cpuTime) / 1e6 + if (cpuMs > this.isolateAccumulatedTimeout) { + throw new ExecutionTimeoutError( + `CPU time limit exceeded (${cpuMs}ms > ${this.isolateAccumulatedTimeout}ms)` + ) + } + } + + code = `${this.moduleHandler.generateImports()};results.out=${this.codeWrapper( + code + )};` + + const script = this.isolate.compileModuleSync(code) + + script.instantiateSync(this.vm, specifier => { + const module = this.moduleHandler.getModule(specifier) + if (module) { + return module + } + + throw new Error(`"${specifier}" import not allowed`) + }) + + script.evaluateSync({ timeout: this.invocationTimeout }) + + const result = this.getFromContext(this.resultKey) + return result.out + } + + private registerCallbacks(functions: Record) { + const libId = crypto.randomUUID().replace(/-/g, "") + + const x: Record = {} + for (const [funcName, func] of Object.entries(functions)) { + const key = `f${libId}${funcName}cb` + x[funcName] = key + + this.addToContext({ + [key]: new ivm.Callback((...params: any[]) => (func as any)(...params)), + }) + } + + const mod = + `{` + + Object.entries(x) + .map(([key, func]) => `${key}: ${func}`) + .join() + + "}" + return mod + } + + private addToContext(context: Record) { + for (let key in context) { + const value = context[key] + this.jail.setSync( + key, + typeof value === "function" + ? value + : new ivm.ExternalCopy(value).copyInto({ release: true }) + ) + } + } + + private getFromContext(key: string) { + const ref = this.vm.global.getSync(key, { reference: true }) + const result = ref.copySync() + ref.release() + return result + } +} From 598ebccc2cabf1392b059f74658d20dd56094d55 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 16:08:34 +0100 Subject: [PATCH 064/213] Use wrapper --- packages/server/src/jsRunner/index.ts | 54 +-------- packages/server/src/jsRunner/vm/builtin-vm.ts | 108 ++++++++---------- 2 files changed, 53 insertions(+), 109 deletions(-) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index e39dab1313..c572c112c9 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -1,62 +1,16 @@ import vm from "vm" import env from "../environment" import { setJSRunner, setOnErrorLog } from "@budibase/string-templates" -import { context, logging, timers } from "@budibase/backend-core" +import { logging } from "@budibase/backend-core" import tracer from "dd-trace" import { serializeError } from "serialize-error" - -type TrackerFn = (f: () => T) => T +import { BuiltInVM } from "./vm" export function init() { setJSRunner((js: string, ctx: vm.Context) => { return tracer.trace("runJS", {}, span => { - const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS - let track: TrackerFn = f => f() - if (perRequestLimit) { - const bbCtx = tracer.trace("runJS.getCurrentContext", {}, span => - context.getCurrentContext() - ) - if (bbCtx) { - if (!bbCtx.jsExecutionTracker) { - span?.addTags({ - createdExecutionTracker: true, - }) - bbCtx.jsExecutionTracker = tracer.trace( - "runJS.createExecutionTimeTracker", - {}, - span => timers.ExecutionTimeTracker.withLimit(perRequestLimit) - ) - } - span?.addTags({ - js: { - limitMS: bbCtx.jsExecutionTracker.limitMs, - elapsedMS: bbCtx.jsExecutionTracker.elapsedMS, - }, - }) - // We call checkLimit() here to prevent paying the cost of creating - // a new VM context below when we don't need to. - tracer.trace("runJS.checkLimitAndBind", {}, span => { - bbCtx.jsExecutionTracker!.checkLimit() - track = bbCtx.jsExecutionTracker!.track.bind( - bbCtx.jsExecutionTracker - ) - }) - } - } - - ctx = { - ...ctx, - alert: undefined, - setInterval: undefined, - setTimeout: undefined, - } - - vm.createContext(ctx) - return track(() => - vm.runInNewContext(js, ctx, { - timeout: env.JS_PER_INVOCATION_TIMEOUT_MS, - }) - ) + const vm = new BuiltInVM(ctx, span) + return vm.execute(js) }) }) diff --git a/packages/server/src/jsRunner/vm/builtin-vm.ts b/packages/server/src/jsRunner/vm/builtin-vm.ts index c439603acd..b4c9f775f9 100644 --- a/packages/server/src/jsRunner/vm/builtin-vm.ts +++ b/packages/server/src/jsRunner/vm/builtin-vm.ts @@ -1,75 +1,65 @@ import vm from "vm" import env from "../../environment" -import { setOnErrorLog } from "@budibase/string-templates" -import { context, logging, timers } from "@budibase/backend-core" -import tracer from "dd-trace" -import { serializeError } from "serialize-error" +import { context, timers } from "@budibase/backend-core" +import tracer, { Span } from "dd-trace" import { VM } from "@budibase/types" type TrackerFn = (f: () => T) => T export class BuiltInVM implements VM { private ctx: vm.Context + private span?: Span - constructor(ctx: vm.Context) { + constructor(ctx: vm.Context, span?: Span) { this.ctx = ctx - - if (env.LOG_JS_ERRORS) { - setOnErrorLog((error: Error) => { - logging.logWarn(JSON.stringify(serializeError(error))) - }) - } + this.span = span } execute(code: string) { - return tracer.trace("runJS", {}, span => { - const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS - let track: TrackerFn = f => f() - if (perRequestLimit) { - const bbCtx = tracer.trace("runJS.getCurrentContext", {}, span => - context.getCurrentContext() - ) - if (bbCtx) { - if (!bbCtx.jsExecutionTracker) { - span?.addTags({ - createdExecutionTracker: true, - }) - bbCtx.jsExecutionTracker = tracer.trace( - "runJS.createExecutionTimeTracker", - {}, - span => timers.ExecutionTimeTracker.withLimit(perRequestLimit) - ) - } - span?.addTags({ - js: { - limitMS: bbCtx.jsExecutionTracker.limitMs, - elapsedMS: bbCtx.jsExecutionTracker.elapsedMS, - }, - }) - // We call checkLimit() here to prevent paying the cost of creating - // a new VM context below when we don't need to. - tracer.trace("runJS.checkLimitAndBind", {}, span => { - bbCtx.jsExecutionTracker!.checkLimit() - track = bbCtx.jsExecutionTracker!.track.bind( - bbCtx.jsExecutionTracker - ) - }) - } - } - - this.ctx = { - ...this.ctx, - alert: undefined, - setInterval: undefined, - setTimeout: undefined, - } - - vm.createContext(this.ctx) - return track(() => - vm.runInNewContext(code, this.ctx, { - timeout: env.JS_PER_INVOCATION_TIMEOUT_MS, - }) + const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS + let track: TrackerFn = f => f() + if (perRequestLimit) { + const bbCtx = tracer.trace("runJS.getCurrentContext", {}, span => + context.getCurrentContext() ) - }) + if (bbCtx) { + if (!bbCtx.jsExecutionTracker) { + this.span?.addTags({ + createdExecutionTracker: true, + }) + bbCtx.jsExecutionTracker = tracer.trace( + "runJS.createExecutionTimeTracker", + {}, + span => timers.ExecutionTimeTracker.withLimit(perRequestLimit) + ) + } + this.span?.addTags({ + js: { + limitMS: bbCtx.jsExecutionTracker.limitMs, + elapsedMS: bbCtx.jsExecutionTracker.elapsedMS, + }, + }) + // We call checkLimit() here to prevent paying the cost of creating + // a new VM context below when we don't need to. + tracer.trace("runJS.checkLimitAndBind", {}, span => { + bbCtx.jsExecutionTracker!.checkLimit() + track = bbCtx.jsExecutionTracker!.track.bind(bbCtx.jsExecutionTracker) + }) + } + } + + this.ctx = { + ...this.ctx, + alert: undefined, + setInterval: undefined, + setTimeout: undefined, + } + + vm.createContext(this.ctx) + return track(() => + vm.runInNewContext(code, this.ctx, { + timeout: env.JS_PER_INVOCATION_TIMEOUT_MS, + }) + ) } } From 4cabe612b1919645476649d3a5fb5045a45a7260 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 16:14:01 +0100 Subject: [PATCH 065/213] Create vm2 wrapper --- packages/server/src/jsRunner/vm/index.ts | 1 + packages/server/src/jsRunner/vm/vm2.ts | 26 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 packages/server/src/jsRunner/vm/vm2.ts diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index cc50a5eeaa..01e0daa354 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -1,2 +1,3 @@ export * from "./isolated-vm" export * from "./builtin-vm" +export * from "./vm2" diff --git a/packages/server/src/jsRunner/vm/vm2.ts b/packages/server/src/jsRunner/vm/vm2.ts new file mode 100644 index 0000000000..6d05943d25 --- /dev/null +++ b/packages/server/src/jsRunner/vm/vm2.ts @@ -0,0 +1,26 @@ +import vm2 from "vm2" +import { VM } from "@budibase/types" + +const JS_TIMEOUT_MS = 1000 + +export class VM2 implements VM { + vm: vm2.VM + results: { out: string } + + constructor(context: any) { + this.vm = new vm2.VM({ + timeout: JS_TIMEOUT_MS, + }) + this.results = { out: "" } + this.vm.setGlobals(context) + this.vm.setGlobal("fetch", fetch) + this.vm.setGlobal("results", this.results) + } + + execute(script: string) { + const code = `let fn = () => {\n${script}\n}; results.out = fn();` + const vmScript = new vm2.VMScript(code) + this.vm.run(vmScript) + return this.results.out + } +} From 1367cf36360da1ac8dd9f202be54ebfc956f0250 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 16:17:19 +0100 Subject: [PATCH 066/213] Use wrappers --- packages/server/src/api/controllers/script.ts | 7 +++-- packages/server/src/threads/query.ts | 8 ++--- packages/server/src/utilities/scriptRunner.ts | 29 ------------------- 3 files changed, 8 insertions(+), 36 deletions(-) delete mode 100644 packages/server/src/utilities/scriptRunner.ts diff --git a/packages/server/src/api/controllers/script.ts b/packages/server/src/api/controllers/script.ts index d5b99d0733..f00383615e 100644 --- a/packages/server/src/api/controllers/script.ts +++ b/packages/server/src/api/controllers/script.ts @@ -1,10 +1,11 @@ -import ScriptRunner from "../../utilities/scriptRunner" import { Ctx } from "@budibase/types" +import { VM2 } from "../../jsRunner/vm" export async function execute(ctx: Ctx) { const { script, context } = ctx.request.body - const runner = new ScriptRunner(script, context) - ctx.body = runner.execute() + const runner = new VM2(context) + const result = runner.execute(script) + ctx.body = result } export async function save(ctx: Ctx) { diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index 6b11ce4759..429d058ef7 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -7,7 +7,7 @@ import { QueryVariable, QueryResponse, } from "./definitions" -import ScriptRunner from "../utilities/scriptRunner" +import { VM2 } from "../jsRunner/vm" import { getIntegration } from "../integrations" import { processStringSync } from "@budibase/string-templates" import { context, cache, auth } from "@budibase/backend-core" @@ -26,7 +26,7 @@ class QueryRunner { fields: any parameters: any pagination: any - transformer: any + transformer: string cachedVariables: any[] ctx: any queryResponse: any @@ -127,11 +127,11 @@ class QueryRunner { // transform as required if (transformer) { - const runner = new ScriptRunner(transformer, { + const runner = new VM2({ data: rows, params: enrichedParameters, }) - rows = runner.execute() + rows = runner.execute(transformer) } // if the request fails we retry once, invalidating the cached value diff --git a/packages/server/src/utilities/scriptRunner.ts b/packages/server/src/utilities/scriptRunner.ts deleted file mode 100644 index fee0215d2e..0000000000 --- a/packages/server/src/utilities/scriptRunner.ts +++ /dev/null @@ -1,29 +0,0 @@ -import fetch from "node-fetch" -import { VM, VMScript } from "vm2" - -const JS_TIMEOUT_MS = 1000 - -class ScriptRunner { - vm: VM - results: { out: string } - script: VMScript - - constructor(script: string, context: any) { - const code = `let fn = () => {\n${script}\n}; results.out = fn();` - this.vm = new VM({ - timeout: JS_TIMEOUT_MS, - }) - this.results = { out: "" } - this.vm.setGlobals(context) - this.vm.setGlobal("fetch", fetch) - this.vm.setGlobal("results", this.results) - this.script = new VMScript(code) - } - - execute() { - this.vm.run(this.script) - return this.results.out - } -} - -export default ScriptRunner From d81ecbd7cf5e7f0b7d4628b6c15c7c40231d7d58 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 16:40:32 +0100 Subject: [PATCH 067/213] Add environment --- packages/server/src/environment.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index 20142776b8..bc4b9eb35b 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -126,6 +126,10 @@ const environment = { getDefaults: () => { return DEFAULTS }, + useIsolatedVM: { + QUERY_TRANSFORMERS: !!process.env.QUERY_TRANSFORMERS_ISOLATEDVM, + JS_RUNNER: !!process.env.JS_RUNNER_ISOLATEDVM, + }, } // clean up any environment variable edge cases From 09dbc694fab39a24b15db2c3e3cb3f30b6fb6c49 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 17:01:27 +0100 Subject: [PATCH 068/213] Fix imports --- packages/server/src/threads/query.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index 11714c9c52..a8aa428b0a 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -18,7 +18,7 @@ import { Datasource, Query, SourceName, VM } from "@budibase/types" import { isSQL } from "../integrations/utils" import { interpolateSQL } from "../integrations/queries/sql" -import environment from "src/environment" +import environment from "../environment" class QueryRunner { datasource: Datasource From ae7a978998d3a52a85557c006a5e87045a6a5f00 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 17:27:01 +0100 Subject: [PATCH 069/213] Fix tests --- packages/server/src/environment.ts | 33 ++++++++++--------- packages/server/src/jsRunner/index.ts | 3 +- .../src/jsRunner/tests/jsRunner.spec.ts | 14 ++++++-- packages/server/src/threads/query.ts | 2 +- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index bc4b9eb35b..e137c342e6 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -113,6 +113,7 @@ const environment = { process.env[key] = value // @ts-ignore environment[key] = value + cleanVariables() }, isTest: coreEnv.isTest, isJest: coreEnv.isJest, @@ -126,24 +127,26 @@ const environment = { getDefaults: () => { return DEFAULTS }, - useIsolatedVM: { - QUERY_TRANSFORMERS: !!process.env.QUERY_TRANSFORMERS_ISOLATEDVM, - JS_RUNNER: !!process.env.JS_RUNNER_ISOLATEDVM, - }, + ISOLATEDVM_QUERY_TRANSFORMERS: !!process.env.ISOLATEDVM_QUERY_TRANSFORMERS, + ISOLATEDVM_JS_RUNNER: !!process.env.ISOLATEDVM_JS_RUNNER, } -// clean up any environment variable edge cases -for (let [key, value] of Object.entries(environment)) { - // handle the edge case of "0" to disable an environment variable - if (value === "0") { - // @ts-ignore - environment[key] = 0 - } - // handle the edge case of "false" to disable an environment variable - if (value === "false") { - // @ts-ignore - environment[key] = 0 +function cleanVariables() { + // clean up any environment variable edge cases + for (let [key, value] of Object.entries(environment)) { + // handle the edge case of "0" to disable an environment variable + if (value === "0") { + // @ts-ignore + environment[key] = 0 + } + // handle the edge case of "false" to disable an environment variable + if (value === "false") { + // @ts-ignore + environment[key] = 0 + } } } +cleanVariables() + export default environment diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index 5c863e2855..362dde1fb2 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -7,7 +7,8 @@ import { BuiltInVM, IsolatedVM } from "./vm" export function init() { setJSRunner((js: string, ctx: Record) => { return tracer.trace("runJS", {}, span => { - if (!env.useIsolatedVM.JS_RUNNER) { + const useIsolatedVm = env.ISOLATEDVM_JS_RUNNER + if (!useIsolatedVm) { const vm = new BuiltInVM(ctx, span) return vm.execute(js) } diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts index 285ade7097..3baf049eae 100644 --- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts +++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts @@ -7,18 +7,28 @@ const { runJsHelpersTests } = require("@budibase/string-templates/test/utils") import tk from "timekeeper" import { init } from ".." import TestConfiguration from "../../tests/utilities/TestConfiguration" +import environment from "../../environment" tk.freeze("2021-01-21T12:00:00") -describe("jsRunner", () => { +describe.each([ + ["vm", false], + ["isolated-vm", true], +])("jsRunner (using %s)", (_, useIsolatedVM) => { const config = new TestConfiguration() beforeAll(async () => { + environment._set("ISOLATEDVM_JS_RUNNER", useIsolatedVM) + // Register js runner init() await config.init() }) + afterAll(() => { + config.end() + }) + const processJS = (js: string, context?: object) => { return config.doInContext(config.getAppId(), async () => processStringSync(encodeJSBinding(js), context || {}) @@ -30,7 +40,7 @@ describe("jsRunner", () => { expect(output).toBe(3) }) - it("should prevent sandbox escape", async () => { + it.only("should prevent sandbox escape", async () => { const output = await processJS( `return this.constructor.constructor("return process")()` ) diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index a8aa428b0a..2c8e59ce64 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -129,7 +129,7 @@ class QueryRunner { // transform as required if (transformer) { let runner: VM - if (!environment.useIsolatedVM.QUERY_TRANSFORMERS) { + if (!environment.ISOLATEDVM_QUERY_TRANSFORMERS) { runner = new VM2({ data: rows, params: enrichedParameters, From 804f061a7014568f5f6e3ff2a1bd6d2f3d65a81b Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 17:32:33 +0100 Subject: [PATCH 070/213] Fix test --- packages/server/src/jsRunner/tests/jsRunner.spec.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts index 3baf049eae..e7fe658737 100644 --- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts +++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts @@ -1,3 +1,5 @@ +import vm from "vm" + import { validate as isValidUUID } from "uuid" import { processStringSync, encodeJSBinding } from "@budibase/string-templates" @@ -40,11 +42,16 @@ describe.each([ expect(output).toBe(3) }) - it.only("should prevent sandbox escape", async () => { + it("should prevent sandbox escape", async () => { const output = await processJS( - `return this.constructor.constructor("return process")()` + `return this.constructor.constructor("return process.env")()` ) - expect(output).toBe("Error while executing JS") + if (useIsolatedVM) { + expect(output).toBe("Error while executing JS") + } else { + expect(output).not.toBe("Error while executing JS") + expect(output).toEqual(process.env) + } }) describe("helpers", () => { From c3c39b1c1b6973d943946c9f157ac6ed126f66d0 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 17:32:55 +0100 Subject: [PATCH 071/213] Add comment --- packages/server/src/jsRunner/tests/jsRunner.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts index e7fe658737..9f2a7c61d7 100644 --- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts +++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts @@ -49,6 +49,7 @@ describe.each([ if (useIsolatedVM) { expect(output).toBe("Error while executing JS") } else { + // This was not an issue without isolated-vm expect(output).not.toBe("Error while executing JS") expect(output).toEqual(process.env) } From 6cd6b21f83c62e7a1a022c606f2317b34c9270f4 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 17:37:25 +0100 Subject: [PATCH 072/213] Fix build --- packages/server/src/jsRunner/vm/isolated-vm.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/server/src/jsRunner/vm/isolated-vm.ts b/packages/server/src/jsRunner/vm/isolated-vm.ts index 0285af8620..12559df0b7 100644 --- a/packages/server/src/jsRunner/vm/isolated-vm.ts +++ b/packages/server/src/jsRunner/vm/isolated-vm.ts @@ -7,6 +7,7 @@ import querystring from "querystring" import { BundleType, loadBundle } from "../bundles" import { VM } from "@budibase/types" +import environment from "../../environment" class ExecutionTimeoutError extends Error { constructor(message: string) { @@ -33,10 +34,13 @@ export class IsolatedVM implements VM { invocationTimeout, isolateAccumulatedTimeout, }: { - memoryLimit: number - invocationTimeout: number + memoryLimit?: number + invocationTimeout?: number isolateAccumulatedTimeout?: number - }) { + } = {}) { + memoryLimit = memoryLimit || environment.JS_RUNNER_MEMORY_LIMIT + invocationTimeout = memoryLimit || 1000 + this.isolate = new ivm.Isolate({ memoryLimit }) this.vm = this.isolate.createContextSync() this.jail = this.vm.global From 865e9ac1112ad5150d865e79a3d84bd8681b2c1b Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 19 Feb 2024 17:50:27 +0000 Subject: [PATCH 073/213] Setting environment variables for isolated-vm to always be used. --- packages/server/src/environment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index e137c342e6..bb3349c7b4 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -107,6 +107,8 @@ const environment = { parseIntSafe(process.env.JS_RUNNER_MEMORY_LIMIT) || DEFAULTS.JS_RUNNER_MEMORY_LIMIT, LOG_JS_ERRORS: process.env.LOG_JS_ERRORS, + ISOLATEDVM_QUERY_TRANSFORMERS: true, + ISOLATEDVM_JS_RUNNER: true, // old CLIENT_ID: process.env.CLIENT_ID, _set(key: string, value: any) { @@ -127,8 +129,6 @@ const environment = { getDefaults: () => { return DEFAULTS }, - ISOLATEDVM_QUERY_TRANSFORMERS: !!process.env.ISOLATEDVM_QUERY_TRANSFORMERS, - ISOLATEDVM_JS_RUNNER: !!process.env.ISOLATEDVM_JS_RUNNER, } function cleanVariables() { From 87d60ca5f2a56777d50d565332ab393d617c2741 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 19 Feb 2024 17:55:04 +0000 Subject: [PATCH 074/213] Removing env vars to disable isolated-vm usage. --- packages/server/src/jsRunner/index.ts | 8 ++++---- .../src/jsRunner/tests/jsRunner.spec.ts | 19 ++----------------- packages/server/src/threads/query.ts | 5 +++-- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index 362dde1fb2..c70c239c48 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -4,11 +4,12 @@ import { context } from "@budibase/backend-core" import tracer from "dd-trace" import { BuiltInVM, IsolatedVM } from "./vm" +const USE_ISOLATED_VM = true + export function init() { setJSRunner((js: string, ctx: Record) => { return tracer.trace("runJS", {}, span => { - const useIsolatedVm = env.ISOLATEDVM_JS_RUNNER - if (!useIsolatedVm) { + if (!USE_ISOLATED_VM) { const vm = new BuiltInVM(ctx, span) return vm.execute(js) } @@ -31,8 +32,7 @@ export function init() { bbCtx.vm = vm } - const result = vm.execute(js) - return result + return vm.execute(js) } catch (error: any) { if (error.message === "Script execution timed out.") { throw new JsErrorTimeout() diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts index 18dc694b3c..30e29885b1 100644 --- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts +++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts @@ -1,7 +1,4 @@ -import vm from "vm" - import { validate as isValidUUID } from "uuid" - import { processStringSync, encodeJSBinding } from "@budibase/string-templates" const { runJsHelpersTests } = require("@budibase/string-templates/test/utils") @@ -9,19 +6,13 @@ const { runJsHelpersTests } = require("@budibase/string-templates/test/utils") import tk from "timekeeper" import { init } from ".." import TestConfiguration from "../../tests/utilities/TestConfiguration" -import environment from "../../environment" tk.freeze("2021-01-21T12:00:00") -describe.each([ - ["vm", false], - ["isolated-vm", true], -])("jsRunner (using %s)", (_, useIsolatedVM) => { +describe("jsRunner (using isolated-vm)", () => { const config = new TestConfiguration() beforeAll(async () => { - environment._set("ISOLATEDVM_JS_RUNNER", useIsolatedVM) - // Register js runner init() await config.init() @@ -51,13 +42,7 @@ describe.each([ const output = await processJS( `return this.constructor.constructor("return process.env")()` ) - if (useIsolatedVM) { - expect(output).toBe("Error while executing JS") - } else { - // This was not an issue without isolated-vm - expect(output).not.toBe("Error while executing JS") - expect(output).toEqual(process.env) - } + expect(output).toBe("Error while executing JS") }) describe("helpers", () => { diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index 2c8e59ce64..1f28034f60 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -18,7 +18,8 @@ import { Datasource, Query, SourceName, VM } from "@budibase/types" import { isSQL } from "../integrations/utils" import { interpolateSQL } from "../integrations/queries/sql" -import environment from "../environment" + +const USE_ISOLATED_VM = true class QueryRunner { datasource: Datasource @@ -129,7 +130,7 @@ class QueryRunner { // transform as required if (transformer) { let runner: VM - if (!environment.ISOLATEDVM_QUERY_TRANSFORMERS) { + if (!USE_ISOLATED_VM) { runner = new VM2({ data: rows, params: enrichedParameters, From 74fbb901f9aa7e9165dfa477c5b3e934a0c54da6 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 19 Feb 2024 17:57:16 +0000 Subject: [PATCH 075/213] Removing unused environment variables. --- packages/server/src/environment.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index bb3349c7b4..873c392942 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -107,8 +107,6 @@ const environment = { parseIntSafe(process.env.JS_RUNNER_MEMORY_LIMIT) || DEFAULTS.JS_RUNNER_MEMORY_LIMIT, LOG_JS_ERRORS: process.env.LOG_JS_ERRORS, - ISOLATEDVM_QUERY_TRANSFORMERS: true, - ISOLATEDVM_JS_RUNNER: true, // old CLIENT_ID: process.env.CLIENT_ID, _set(key: string, value: any) { From 85052ca36124b3a460e10f44a18988987849c2b9 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 19:34:15 +0100 Subject: [PATCH 076/213] Fix query --- packages/server/src/threads/query.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index 1f28034f60..c159f24268 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -136,6 +136,7 @@ class QueryRunner { params: enrichedParameters, }) } else { + transformer = `(function(){\n${transformer}\n})();` let isolatedVm = new IsolatedVM().withContext({ data: rows, params: enrichedParameters, From 0b84957ad0958d65167f84bfa5da8cd285a1b479 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 19:42:28 +0100 Subject: [PATCH 077/213] Remove vm2 usage from script controllers --- packages/server/src/api/controllers/script.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/api/controllers/script.ts b/packages/server/src/api/controllers/script.ts index f00383615e..7b07b97ba9 100644 --- a/packages/server/src/api/controllers/script.ts +++ b/packages/server/src/api/controllers/script.ts @@ -1,9 +1,9 @@ import { Ctx } from "@budibase/types" -import { VM2 } from "../../jsRunner/vm" +import { IsolatedVM } from "../../jsRunner/vm" export async function execute(ctx: Ctx) { const { script, context } = ctx.request.body - const runner = new VM2(context) + const runner = new IsolatedVM(context) const result = runner.execute(script) ctx.body = result } From 9f5d4811ba9ad8f111f9457c09279d7c1f686e04 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 19:53:36 +0100 Subject: [PATCH 078/213] Improve js logging error message --- packages/server/src/jsRunner/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index c572c112c9..21f1be3c90 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -16,7 +16,9 @@ export function init() { if (env.LOG_JS_ERRORS) { setOnErrorLog((error: Error) => { - logging.logWarn(JSON.stringify(serializeError(error))) + logging.logWarn( + `Error while executing js: ${JSON.stringify(serializeError(error))}` + ) }) } } From 282a3ee3b943c1d9e8e4a82b3ca56b69e18c67ca Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 19:58:41 +0100 Subject: [PATCH 079/213] Fix test --- packages/server/src/api/controllers/script.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/server/src/api/controllers/script.ts b/packages/server/src/api/controllers/script.ts index 7b07b97ba9..9a404da9fb 100644 --- a/packages/server/src/api/controllers/script.ts +++ b/packages/server/src/api/controllers/script.ts @@ -4,7 +4,8 @@ import { IsolatedVM } from "../../jsRunner/vm" export async function execute(ctx: Ctx) { const { script, context } = ctx.request.body const runner = new IsolatedVM(context) - const result = runner.execute(script) + + const result = runner.execute(`(function(){\n${script}\n})();`) ctx.body = result } From 2042a9580575b04620ed8d6afbc3fc915d9b3a6c Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 20:12:46 +0100 Subject: [PATCH 080/213] Fix runs --- packages/server/src/api/controllers/script.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/api/controllers/script.ts b/packages/server/src/api/controllers/script.ts index 9a404da9fb..bdca2d6e18 100644 --- a/packages/server/src/api/controllers/script.ts +++ b/packages/server/src/api/controllers/script.ts @@ -3,7 +3,7 @@ import { IsolatedVM } from "../../jsRunner/vm" export async function execute(ctx: Ctx) { const { script, context } = ctx.request.body - const runner = new IsolatedVM(context) + const runner = new IsolatedVM().withContext(context) const result = runner.execute(`(function(){\n${script}\n})();`) ctx.body = result From c52b6aa0d1e7f836401deebfd16d198d738f4162 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 19 Feb 2024 19:37:18 +0000 Subject: [PATCH 081/213] Some initial test cases for isolated VM. --- .../src/jsRunner/tests/isolatedVM.spec.ts | 33 + .../src/jsRunner/tests/jsRunner.spec.ts | 75 + packages/server/src/jsRunner/tests/marked.txt | 3018 +++++++++++++++++ 3 files changed, 3126 insertions(+) create mode 100644 packages/server/src/jsRunner/tests/isolatedVM.spec.ts create mode 100644 packages/server/src/jsRunner/tests/marked.txt diff --git a/packages/server/src/jsRunner/tests/isolatedVM.spec.ts b/packages/server/src/jsRunner/tests/isolatedVM.spec.ts new file mode 100644 index 0000000000..0bd400c8d7 --- /dev/null +++ b/packages/server/src/jsRunner/tests/isolatedVM.spec.ts @@ -0,0 +1,33 @@ +import fs from "fs" +import path from "path" +import { IsolatedVM, VM2 } from "../vm" + +function runJSWithIsolatedVM(script: string, context?: any) { + const runner = new IsolatedVM() + if (context) { + runner.withContext(context) + } + return runner.execute(`(function(){\n${script}\n})();`) +} + +function runJSWithVM2(script: string, context?: any) { + const runner = new VM2(context) + return runner.execute(script) +} + +function compare(script: string, context?: any) { + const resultIsolated = runJSWithIsolatedVM(script, context) + const resultVM = runJSWithVM2(script, context) + expect(resultIsolated).toEqual(resultVM) + return resultIsolated +} + +describe("Test isolated vm directly", () => { + it("should handle a very large file", () => { + const marked = fs.readFileSync(path.join(__dirname, "marked.txt"), "utf-8") + const result = compare(marked, { + trigger: { row: { Message: "dddd" } }, + }) + expect(result).toBe("

dddd

\n") + }) +}) diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts index 30e29885b1..9bb9052eda 100644 --- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts +++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts @@ -1,5 +1,7 @@ import { validate as isValidUUID } from "uuid" import { processStringSync, encodeJSBinding } from "@budibase/string-templates" +import fs from "fs" +import path from "path" const { runJsHelpersTests } = require("@budibase/string-templates/test/utils") @@ -70,4 +72,77 @@ describe("jsRunner (using isolated-vm)", () => { }) }) }) + + // the test cases here were extracted from templates/real world examples of JS in Budibase + describe("should real world tests of JS", () => { + const context = { + "Unit Value": 2, + Quantity: 1, + } + it("handle test case 1", async () => { + const result = await processJS( + ` + var Gross = $("[Unit Value]") * $("[Quantity]") + return Gross.toFixed(2)`, + context + ) + expect(result).toBeDefined() + expect(result).toBe("2.00") + }) + + it("handle test case 2", async () => { + const context = { + "Purchase Date": "2021-01-21T12:00:00", + } + const result = await processJS( + ` + var purchase = new Date($("[Purchase Date]")); + let purchaseyear = purchase.getFullYear(); + let purchasemonth = purchase.getMonth(); + + var today = new Date (); + let todayyear = today.getFullYear(); + let todaymonth = today.getMonth(); + + var age = todayyear - purchaseyear + + if (((todaymonth - purchasemonth) < 6) == true){ + return age + } + `, + context + ) + expect(result).toBeDefined() + expect(result).toBe(3) + }) + + it("should handle test case 3", async () => { + const context = { + Escalate: true, + "Budget ($)": 1100, + } + const result = await processJS( + ` + if ($("[Escalate]") == true) { + if ($("Budget ($)") <= 1000) + {return 2;} + if ($("Budget ($)") > 1000) + {return 3;} + } + else { + if ($("Budget ($)") <= 1000) + {return 1;} + if ($("Budget ($)") > 1000) + if ($("Budget ($)") < 10000) + {return 2;} + else + {return 3} + } + `, + context + ) + expect(result).toBeDefined() + expect(result).toBe(3) + }) + }) }) diff --git a/packages/server/src/jsRunner/tests/marked.txt b/packages/server/src/jsRunner/tests/marked.txt new file mode 100644 index 0000000000..c5c01d7f0f --- /dev/null +++ b/packages/server/src/jsRunner/tests/marked.txt @@ -0,0 +1,3018 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2022, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ + +/** + * DO NOT EDIT THIS FILE + * The code in this file is generated from files in ./src/ + */ + +function getDefaults() { + return { + baseUrl: null, + breaks: false, + extensions: null, + gfm: true, + headerIds: true, + headerPrefix: "", + highlight: null, + langPrefix: "language-", + mangle: true, + pedantic: false, + renderer: null, + sanitize: false, + sanitizer: null, + silent: false, + smartLists: false, + smartypants: false, + tokenizer: null, + walkTokens: null, + xhtml: false, + } +} + +let defaults = getDefaults() + +function changeDefaults(newDefaults) { + defaults = newDefaults +} + +/** + * Helpers + */ +const escapeTest = /[&<>"']/ +const escapeReplace = /[&<>"']/g +const escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/ +const escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g +const escapeReplacements = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", +} +const getEscapeReplacement = ch => escapeReplacements[ch] +function escape(html, encode) { + if (encode) { + if (escapeTest.test(html)) { + return html.replace(escapeReplace, getEscapeReplacement) + } + } else { + if (escapeTestNoEncode.test(html)) { + return html.replace(escapeReplaceNoEncode, getEscapeReplacement) + } + } + + return html +} + +const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi + +/** + * @param {string} html + */ +function unescape(html) { + // explicitly match decimal, hex, and named HTML entities + return html.replace(unescapeTest, (_, n) => { + n = n.toLowerCase() + if (n === "colon") return ":" + if (n.charAt(0) === "#") { + return n.charAt(1) === "x" + ? String.fromCharCode(parseInt(n.substring(2), 16)) + : String.fromCharCode(+n.substring(1)) + } + return "" + }) +} + +const caret = /(^|[^\[])\^/g + +/** + * @param {string | RegExp} regex + * @param {string} opt + */ +function edit(regex, opt) { + regex = typeof regex === "string" ? regex : regex.source + opt = opt || "" + const obj = { + replace: (name, val) => { + val = val.source || val + val = val.replace(caret, "$1") + regex = regex.replace(name, val) + return obj + }, + getRegex: () => { + return new RegExp(regex, opt) + }, + } + return obj +} + +const nonWordAndColonTest = /[^\w:]/g +const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i + +/** + * @param {boolean} sanitize + * @param {string} base + * @param {string} href + */ +function cleanUrl(sanitize, base, href) { + if (sanitize) { + let prot + try { + prot = decodeURIComponent(unescape(href)) + .replace(nonWordAndColonTest, "") + .toLowerCase() + } catch (e) { + return null + } + if ( + prot.indexOf("javascript:") === 0 || + prot.indexOf("vbscript:") === 0 || + prot.indexOf("data:") === 0 + ) { + return null + } + } + if (base && !originIndependentUrl.test(href)) { + href = resolveUrl(base, href) + } + try { + href = encodeURI(href).replace(/%25/g, "%") + } catch (e) { + return null + } + return href +} + +const baseUrls = {} +const justDomain = /^[^:]+:\/*[^/]*$/ +const protocol = /^([^:]+:)[\s\S]*$/ +const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/ + +/** + * @param {string} base + * @param {string} href + */ +function resolveUrl(base, href) { + if (!baseUrls[" " + base]) { + // we can ignore everything in base after the last slash of its path component, + // but we might need to add _that_ + // https://tools.ietf.org/html/rfc3986#section-3 + if (justDomain.test(base)) { + baseUrls[" " + base] = base + "/" + } else { + baseUrls[" " + base] = rtrim(base, "/", true) + } + } + base = baseUrls[" " + base] + const relativeBase = base.indexOf(":") === -1 + + if (href.substring(0, 2) === "//") { + if (relativeBase) { + return href + } + return base.replace(protocol, "$1") + href + } else if (href.charAt(0) === "/") { + if (relativeBase) { + return href + } + return base.replace(domain, "$1") + href + } else { + return base + href + } +} + +const noopTest = { exec: function noopTest() {} } + +function merge(obj) { + let i = 1, + target, + key + + for (; i < arguments.length; i++) { + target = arguments[i] + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key] + } + } + } + + return obj +} + +function splitCells(tableRow, count) { + // ensure that every cell-delimiting pipe has a space + // before it to distinguish it from an escaped pipe + const row = tableRow.replace(/\|/g, (match, offset, str) => { + let escaped = false, + curr = offset + while (--curr >= 0 && str[curr] === "\\") escaped = !escaped + if (escaped) { + // odd number of slashes means | is escaped + // so we leave it alone + return "|" + } else { + // add space before unescaped | + return " |" + } + }), + cells = row.split(/ \|/) + let i = 0 + + // First/last cell in a row cannot be empty if it has no leading/trailing pipe + if (!cells[0].trim()) { + cells.shift() + } + if (cells.length > 0 && !cells[cells.length - 1].trim()) { + cells.pop() + } + + if (cells.length > count) { + cells.splice(count) + } else { + while (cells.length < count) cells.push("") + } + + for (; i < cells.length; i++) { + // leading or trailing whitespace is ignored per the gfm spec + cells[i] = cells[i].trim().replace(/\\\|/g, "|") + } + return cells +} + +/** + * Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). + * /c*$/ is vulnerable to REDOS. + * + * @param {string} str + * @param {string} c + * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey. + */ +function rtrim(str, c, invert) { + const l = str.length + if (l === 0) { + return "" + } + + // Length of suffix matching the invert condition. + let suffLen = 0 + + // Step left until we fail to match the invert condition. + while (suffLen < l) { + const currChar = str.charAt(l - suffLen - 1) + if (currChar === c && !invert) { + suffLen++ + } else if (currChar !== c && invert) { + suffLen++ + } else { + break + } + } + + return str.slice(0, l - suffLen) +} + +function findClosingBracket(str, b) { + if (str.indexOf(b[1]) === -1) { + return -1 + } + const l = str.length + let level = 0, + i = 0 + for (; i < l; i++) { + if (str[i] === "\\") { + i++ + } else if (str[i] === b[0]) { + level++ + } else if (str[i] === b[1]) { + level-- + if (level < 0) { + return i + } + } + } + return -1 +} + +function checkSanitizeDeprecation(opt) { + if (opt && opt.sanitize && !opt.silent) { + console.warn( + "marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options" + ) + } +} + +// copied from https://stackoverflow.com/a/5450113/806777 +/** + * @param {string} pattern + * @param {number} count + */ +function repeatString(pattern, count) { + if (count < 1) { + return "" + } + let result = "" + while (count > 1) { + if (count & 1) { + result += pattern + } + count >>= 1 + pattern += pattern + } + return result + pattern +} + +function outputLink(cap, link, raw, lexer) { + const href = link.href + const title = link.title ? escape(link.title) : null + const text = cap[1].replace(/\\([\[\]])/g, "$1") + + if (cap[0].charAt(0) !== "!") { + lexer.state.inLink = true + const token = { + type: "link", + raw, + href, + title, + text, + tokens: lexer.inlineTokens(text, []), + } + lexer.state.inLink = false + return token + } + return { + type: "image", + raw, + href, + title, + text: escape(text), + } +} + +function indentCodeCompensation(raw, text) { + const matchIndentToCode = raw.match(/^(\s+)(?:```)/) + + if (matchIndentToCode === null) { + return text + } + + const indentToCode = matchIndentToCode[1] + + return text + .split("\n") + .map(node => { + const matchIndentInNode = node.match(/^\s+/) + if (matchIndentInNode === null) { + return node + } + + const [indentInNode] = matchIndentInNode + + if (indentInNode.length >= indentToCode.length) { + return node.slice(indentToCode.length) + } + + return node + }) + .join("\n") +} + +/** + * Tokenizer + */ +class Tokenizer { + constructor(options) { + this.options = options || defaults + } + + space(src) { + const cap = this.rules.block.newline.exec(src) + if (cap && cap[0].length > 0) { + return { + type: "space", + raw: cap[0], + } + } + } + + code(src) { + const cap = this.rules.block.code.exec(src) + if (cap) { + const text = cap[0].replace(/^ {1,4}/gm, "") + return { + type: "code", + raw: cap[0], + codeBlockStyle: "indented", + text: !this.options.pedantic ? rtrim(text, "\n") : text, + } + } + } + + fences(src) { + const cap = this.rules.block.fences.exec(src) + if (cap) { + const raw = cap[0] + const text = indentCodeCompensation(raw, cap[3] || "") + + return { + type: "code", + raw, + lang: cap[2] ? cap[2].trim() : cap[2], + text, + } + } + } + + heading(src) { + const cap = this.rules.block.heading.exec(src) + if (cap) { + let text = cap[2].trim() + + // remove trailing #s + if (/#$/.test(text)) { + const trimmed = rtrim(text, "#") + if (this.options.pedantic) { + text = trimmed.trim() + } else if (!trimmed || / $/.test(trimmed)) { + // CommonMark requires space before trailing #s + text = trimmed.trim() + } + } + + const token = { + type: "heading", + raw: cap[0], + depth: cap[1].length, + text, + tokens: [], + } + this.lexer.inline(token.text, token.tokens) + return token + } + } + + hr(src) { + const cap = this.rules.block.hr.exec(src) + if (cap) { + return { + type: "hr", + raw: cap[0], + } + } + } + + blockquote(src) { + const cap = this.rules.block.blockquote.exec(src) + if (cap) { + const text = cap[0].replace(/^ *>[ \t]?/gm, "") + + return { + type: "blockquote", + raw: cap[0], + tokens: this.lexer.blockTokens(text, []), + text, + } + } + } + + list(src) { + let cap = this.rules.block.list.exec(src) + if (cap) { + let raw, + istask, + ischecked, + indent, + i, + blankLine, + endsWithBlankLine, + line, + nextLine, + rawLine, + itemContents, + endEarly + + let bull = cap[1].trim() + const isordered = bull.length > 1 + + const list = { + type: "list", + raw: "", + ordered: isordered, + start: isordered ? +bull.slice(0, -1) : "", + loose: false, + items: [], + } + + bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}` + + if (this.options.pedantic) { + bull = isordered ? bull : "[*+-]" + } + + // Get next list item + const itemRegex = new RegExp( + `^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))` + ) + + // Check if current bullet point can start a new List Item + while (src) { + endEarly = false + if (!(cap = itemRegex.exec(src))) { + break + } + + if (this.rules.block.hr.test(src)) { + // End list if bullet was actually HR (possibly move into itemRegex?) + break + } + + raw = cap[0] + src = src.substring(raw.length) + + line = cap[2].split("\n", 1)[0] + nextLine = src.split("\n", 1)[0] + + if (this.options.pedantic) { + indent = 2 + itemContents = line.trimLeft() + } else { + indent = cap[2].search(/[^ ]/) // Find first non-space char + indent = indent > 4 ? 1 : indent // Treat indented code blocks (> 4 spaces) as having only 1 indent + itemContents = line.slice(indent) + indent += cap[1].length + } + + blankLine = false + + if (!line && /^ *$/.test(nextLine)) { + // Items begin with at most one blank line + raw += nextLine + "\n" + src = src.substring(nextLine.length + 1) + endEarly = true + } + + if (!endEarly) { + const nextBulletRegex = new RegExp( + `^ {0,${Math.min( + 3, + indent - 1 + )}}(?:[*+-]|\\d{1,9}[.)])((?: [^\\n]*)?(?:\\n|$))` + ) + const hrRegex = new RegExp( + `^ {0,${Math.min( + 3, + indent - 1 + )}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)` + ) + + // Check if following lines should be included in List Item + while (src) { + rawLine = src.split("\n", 1)[0] + line = rawLine + + // Re-align to follow commonmark nesting rules + if (this.options.pedantic) { + line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, " ") + } + + // End list item if found start of new bullet + if (nextBulletRegex.test(line)) { + break + } + + // Horizontal rule found + if (hrRegex.test(src)) { + break + } + + if (line.search(/[^ ]/) >= indent || !line.trim()) { + // Dedent if possible + itemContents += "\n" + line.slice(indent) + } else if (!blankLine) { + // Until blank line, item doesn't need indentation + itemContents += "\n" + line + } else { + // Otherwise, improper indentation ends this item + break + } + + if (!blankLine && !line.trim()) { + // Check if current line is blank + blankLine = true + } + + raw += rawLine + "\n" + src = src.substring(rawLine.length + 1) + } + } + + if (!list.loose) { + // If the previous item ended with a blank line, the list is loose + if (endsWithBlankLine) { + list.loose = true + } else if (/\n *\n *$/.test(raw)) { + endsWithBlankLine = true + } + } + + // Check for task list items + if (this.options.gfm) { + istask = /^\[[ xX]\] /.exec(itemContents) + if (istask) { + ischecked = istask[0] !== "[ ] " + itemContents = itemContents.replace(/^\[[ xX]\] +/, "") + } + } + + list.items.push({ + type: "list_item", + raw, + task: !!istask, + checked: ischecked, + loose: false, + text: itemContents, + }) + + list.raw += raw + } + + // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic + list.items[list.items.length - 1].raw = raw.trimRight() + list.items[list.items.length - 1].text = itemContents.trimRight() + list.raw = list.raw.trimRight() + + const l = list.items.length + + // Item child tokens handled here at end because we needed to have the final item to trim it first + for (i = 0; i < l; i++) { + this.lexer.state.top = false + list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []) + const spacers = list.items[i].tokens.filter(t => t.type === "space") + const hasMultipleLineBreaks = spacers.every(t => { + const chars = t.raw.split("") + let lineBreaks = 0 + for (const char of chars) { + if (char === "\n") { + lineBreaks += 1 + } + if (lineBreaks > 1) { + return true + } + } + + return false + }) + + if (!list.loose && spacers.length && hasMultipleLineBreaks) { + // Having a single line break doesn't mean a list is loose. A single line break is terminating the last list item + list.loose = true + list.items[i].loose = true + } + } + + return list + } + } + + html(src) { + const cap = this.rules.block.html.exec(src) + if (cap) { + const token = { + type: "html", + raw: cap[0], + pre: + !this.options.sanitizer && + (cap[1] === "pre" || cap[1] === "script" || cap[1] === "style"), + text: cap[0], + } + if (this.options.sanitize) { + token.type = "paragraph" + token.text = this.options.sanitizer + ? this.options.sanitizer(cap[0]) + : escape(cap[0]) + token.tokens = [] + this.lexer.inline(token.text, token.tokens) + } + return token + } + } + + def(src) { + const cap = this.rules.block.def.exec(src) + if (cap) { + if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1) + const tag = cap[1].toLowerCase().replace(/\s+/g, " ") + return { + type: "def", + tag, + raw: cap[0], + href: cap[2], + title: cap[3], + } + } + } + + table(src) { + const cap = this.rules.block.table.exec(src) + if (cap) { + const item = { + type: "table", + header: splitCells(cap[1]).map(c => { + return { text: c } + }), + align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */), + rows: + cap[3] && cap[3].trim() + ? cap[3].replace(/\n[ \t]*$/, "").split("\n") + : [], + } + + if (item.header.length === item.align.length) { + item.raw = cap[0] + + let l = item.align.length + let i, j, k, row + for (i = 0; i < l; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = "right" + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = "center" + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = "left" + } else { + item.align[i] = null + } + } + + l = item.rows.length + for (i = 0; i < l; i++) { + item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => { + return { text: c } + }) + } + + // parse child tokens inside headers and cells + + // header child tokens + l = item.header.length + for (j = 0; j < l; j++) { + item.header[j].tokens = [] + this.lexer.inline(item.header[j].text, item.header[j].tokens) + } + + // cell child tokens + l = item.rows.length + for (j = 0; j < l; j++) { + row = item.rows[j] + for (k = 0; k < row.length; k++) { + row[k].tokens = [] + this.lexer.inline(row[k].text, row[k].tokens) + } + } + + return item + } + } + } + + lheading(src) { + const cap = this.rules.block.lheading.exec(src) + if (cap) { + const token = { + type: "heading", + raw: cap[0], + depth: cap[2].charAt(0) === "=" ? 1 : 2, + text: cap[1], + tokens: [], + } + this.lexer.inline(token.text, token.tokens) + return token + } + } + + paragraph(src) { + const cap = this.rules.block.paragraph.exec(src) + if (cap) { + const token = { + type: "paragraph", + raw: cap[0], + text: + cap[1].charAt(cap[1].length - 1) === "\n" + ? cap[1].slice(0, -1) + : cap[1], + tokens: [], + } + this.lexer.inline(token.text, token.tokens) + return token + } + } + + text(src) { + const cap = this.rules.block.text.exec(src) + if (cap) { + const token = { + type: "text", + raw: cap[0], + text: cap[0], + tokens: [], + } + this.lexer.inline(token.text, token.tokens) + return token + } + } + + escape(src) { + const cap = this.rules.inline.escape.exec(src) + if (cap) { + return { + type: "escape", + raw: cap[0], + text: escape(cap[1]), + } + } + } + + tag(src) { + const cap = this.rules.inline.tag.exec(src) + if (cap) { + if (!this.lexer.state.inLink && /^/i.test(cap[0])) { + this.lexer.state.inLink = false + } + if ( + !this.lexer.state.inRawBlock && + /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0]) + ) { + this.lexer.state.inRawBlock = true + } else if ( + this.lexer.state.inRawBlock && + /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0]) + ) { + this.lexer.state.inRawBlock = false + } + + return { + type: this.options.sanitize ? "text" : "html", + raw: cap[0], + inLink: this.lexer.state.inLink, + inRawBlock: this.lexer.state.inRawBlock, + text: this.options.sanitize + ? this.options.sanitizer + ? this.options.sanitizer(cap[0]) + : escape(cap[0]) + : cap[0], + } + } + } + + link(src) { + const cap = this.rules.inline.link.exec(src) + if (cap) { + const trimmedUrl = cap[2].trim() + if (!this.options.pedantic && /^$/.test(trimmedUrl)) { + return + } + + // ending angle bracket cannot be escaped + const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), "\\") + if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { + return + } + } else { + // find closing parenthesis + const lastParenIndex = findClosingBracket(cap[2], "()") + if (lastParenIndex > -1) { + const start = cap[0].indexOf("!") === 0 ? 5 : 4 + const linkLen = start + cap[1].length + lastParenIndex + cap[2] = cap[2].substring(0, lastParenIndex) + cap[0] = cap[0].substring(0, linkLen).trim() + cap[3] = "" + } + } + let href = cap[2] + let title = "" + if (this.options.pedantic) { + // split pedantic href and title + const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href) + + if (link) { + href = link[1] + title = link[3] + } + } else { + title = cap[3] ? cap[3].slice(1, -1) : "" + } + + href = href.trim() + if (/^$/.test(trimmedUrl)) { + // pedantic allows starting angle bracket without ending angle bracket + href = href.slice(1) + } else { + href = href.slice(1, -1) + } + } + return outputLink( + cap, + { + href: href ? href.replace(this.rules.inline._escapes, "$1") : href, + title: title + ? title.replace(this.rules.inline._escapes, "$1") + : title, + }, + cap[0], + this.lexer + ) + } + } + + reflink(src, links) { + let cap + if ( + (cap = this.rules.inline.reflink.exec(src)) || + (cap = this.rules.inline.nolink.exec(src)) + ) { + let link = (cap[2] || cap[1]).replace(/\s+/g, " ") + link = links[link.toLowerCase()] + if (!link || !link.href) { + const text = cap[0].charAt(0) + return { + type: "text", + raw: text, + text, + } + } + return outputLink(cap, link, cap[0], this.lexer) + } + } + + emStrong(src, maskedSrc, prevChar = "") { + let match = this.rules.inline.emStrong.lDelim.exec(src) + if (!match) return + + // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well + if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) return + + const nextChar = match[1] || match[2] || "" + + if ( + !nextChar || + (nextChar && + (prevChar === "" || this.rules.inline.punctuation.exec(prevChar))) + ) { + const lLength = match[0].length - 1 + let rDelim, + rLength, + delimTotal = lLength, + midDelimTotal = 0 + + const endReg = + match[0][0] === "*" + ? this.rules.inline.emStrong.rDelimAst + : this.rules.inline.emStrong.rDelimUnd + endReg.lastIndex = 0 + + // Clip maskedSrc to same section of string as src (move to lexer?) + maskedSrc = maskedSrc.slice(-1 * src.length + lLength) + + while ((match = endReg.exec(maskedSrc)) != null) { + rDelim = + match[1] || match[2] || match[3] || match[4] || match[5] || match[6] + + if (!rDelim) continue // skip single * in __abc*abc__ + + rLength = rDelim.length + + if (match[3] || match[4]) { + // found another Left Delim + delimTotal += rLength + continue + } else if (match[5] || match[6]) { + // either Left or Right Delim + if (lLength % 3 && !((lLength + rLength) % 3)) { + midDelimTotal += rLength + continue // CommonMark Emphasis Rules 9-10 + } + } + + delimTotal -= rLength + + if (delimTotal > 0) continue // Haven't found enough closing delimiters + + // Remove extra characters. *a*** -> *a* + rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal) + + // Create `em` if smallest delimiter has odd char count. *a*** + if (Math.min(lLength, rLength) % 2) { + const text = src.slice(1, lLength + match.index + rLength) + return { + type: "em", + raw: src.slice(0, lLength + match.index + rLength + 1), + text, + tokens: this.lexer.inlineTokens(text, []), + } + } + + // Create 'strong' if smallest delimiter has even char count. **a*** + const text = src.slice(2, lLength + match.index + rLength - 1) + return { + type: "strong", + raw: src.slice(0, lLength + match.index + rLength + 1), + text, + tokens: this.lexer.inlineTokens(text, []), + } + } + } + } + + codespan(src) { + const cap = this.rules.inline.code.exec(src) + if (cap) { + let text = cap[2].replace(/\n/g, " ") + const hasNonSpaceChars = /[^ ]/.test(text) + const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text) + if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { + text = text.substring(1, text.length - 1) + } + text = escape(text, true) + return { + type: "codespan", + raw: cap[0], + text, + } + } + } + + br(src) { + const cap = this.rules.inline.br.exec(src) + if (cap) { + return { + type: "br", + raw: cap[0], + } + } + } + + del(src) { + const cap = this.rules.inline.del.exec(src) + if (cap) { + return { + type: "del", + raw: cap[0], + text: cap[2], + tokens: this.lexer.inlineTokens(cap[2], []), + } + } + } + + autolink(src, mangle) { + const cap = this.rules.inline.autolink.exec(src) + if (cap) { + let text, href + if (cap[2] === "@") { + text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]) + href = "mailto:" + text + } else { + text = escape(cap[1]) + href = text + } + + return { + type: "link", + raw: cap[0], + text, + href, + tokens: [ + { + type: "text", + raw: text, + text, + }, + ], + } + } + } + + url(src, mangle) { + let cap + if ((cap = this.rules.inline.url.exec(src))) { + let text, href + if (cap[2] === "@") { + text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]) + href = "mailto:" + text + } else { + // do extended autolink path validation + let prevCapZero + do { + prevCapZero = cap[0] + cap[0] = this.rules.inline._backpedal.exec(cap[0])[0] + } while (prevCapZero !== cap[0]) + text = escape(cap[0]) + if (cap[1] === "www.") { + href = "http://" + text + } else { + href = text + } + } + return { + type: "link", + raw: cap[0], + text, + href, + tokens: [ + { + type: "text", + raw: text, + text, + }, + ], + } + } + } + + inlineText(src, smartypants) { + const cap = this.rules.inline.text.exec(src) + if (cap) { + let text + if (this.lexer.state.inRawBlock) { + text = this.options.sanitize + ? this.options.sanitizer + ? this.options.sanitizer(cap[0]) + : escape(cap[0]) + : cap[0] + } else { + text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]) + } + return { + type: "text", + raw: cap[0], + text, + } + } + } +} + +/** + * Block-Level Grammar + */ +const block = { + newline: /^(?: *(?:\n|$))+/, + code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, + fences: + /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/, + hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, + heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, + blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, + list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, + html: + "^ {0,3}(?:" + // optional indentation + "<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)" + // (1) + "|comment[^\\n]*(\\n+|$)" + // (2) + "|<\\?[\\s\\S]*?(?:\\?>\\n*|$)" + // (3) + "|\\n*|$)" + // (4) + "|\\n*|$)" + // (5) + "|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)" + // (6) + "|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)" + // (7) open tag + "|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)" + // (7) closing tag + ")", + def: /^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, + table: noopTest, + lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, + // regex template, placeholders will be replaced according to different paragraph + // interruption rules of commonmark and the original markdown spec: + _paragraph: + /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, + text: /^[^\n]+/, +} + +block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/ +block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/ +block.def = edit(block.def) + .replace("label", block._label) + .replace("title", block._title) + .getRegex() + +block.bullet = /(?:[*+-]|\d{1,9}[.)])/ +block.listItemStart = edit(/^( *)(bull) */) + .replace("bull", block.bullet) + .getRegex() + +block.list = edit(block.list) + .replace(/bull/g, block.bullet) + .replace( + "hr", + "\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))" + ) + .replace("def", "\\n+(?=" + block.def.source + ")") + .getRegex() + +block._tag = + "address|article|aside|base|basefont|blockquote|body|caption" + + "|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption" + + "|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe" + + "|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option" + + "|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr" + + "|track|ul" +block._comment = /|$)/ +block.html = edit(block.html, "i") + .replace("comment", block._comment) + .replace("tag", block._tag) + .replace( + "attribute", + / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/ + ) + .getRegex() + +block.paragraph = edit(block._paragraph) + .replace("hr", block.hr) + .replace("heading", " {0,3}#{1,6} ") + .replace("|lheading", "") // setex headings don't interrupt commonmark paragraphs + .replace("|table", "") + .replace("blockquote", " {0,3}>") + .replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n") + .replace("list", " {0,3}(?:[*+-]|1[.)]) ") // only lists starting from 1 can interrupt + .replace( + "html", + ")|<(?:script|pre|style|textarea|!--)" + ) + .replace("tag", block._tag) // pars can be interrupted by type (6) html blocks + .getRegex() + +block.blockquote = edit(block.blockquote) + .replace("paragraph", block.paragraph) + .getRegex() + +/** + * Normal Block Grammar + */ + +block.normal = merge({}, block) + +/** + * GFM Block Grammar + */ + +block.gfm = merge({}, block.normal, { + table: + "^ *([^\\n ].*\\|.*)\\n" + // Header + " {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?" + // Align + "(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)", // Cells +}) + +block.gfm.table = edit(block.gfm.table) + .replace("hr", block.hr) + .replace("heading", " {0,3}#{1,6} ") + .replace("blockquote", " {0,3}>") + .replace("code", " {4}[^\\n]") + .replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n") + .replace("list", " {0,3}(?:[*+-]|1[.)]) ") // only lists starting from 1 can interrupt + .replace( + "html", + ")|<(?:script|pre|style|textarea|!--)" + ) + .replace("tag", block._tag) // tables can be interrupted by type (6) html blocks + .getRegex() + +block.gfm.paragraph = edit(block._paragraph) + .replace("hr", block.hr) + .replace("heading", " {0,3}#{1,6} ") + .replace("|lheading", "") // setex headings don't interrupt commonmark paragraphs + .replace("table", block.gfm.table) // interrupt paragraphs with table + .replace("blockquote", " {0,3}>") + .replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n") + .replace("list", " {0,3}(?:[*+-]|1[.)]) ") // only lists starting from 1 can interrupt + .replace( + "html", + ")|<(?:script|pre|style|textarea|!--)" + ) + .replace("tag", block._tag) // pars can be interrupted by type (6) html blocks + .getRegex() +/** + * Pedantic grammar (original John Gruber's loose markdown specification) + */ + +block.pedantic = merge({}, block.normal, { + html: edit( + "^ *(?:comment *(?:\\n|\\s*$)" + + "|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)" + // closed tag + "|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))" + ) + .replace("comment", block._comment) + .replace( + /tag/g, + "(?!(?:" + + "a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub" + + "|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)" + + "\\b)\\w+(?!:|[^\\w\\s@]*@)\\b" + ) + .getRegex(), + def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, + heading: /^(#{1,6})(.*)(?:\n+|$)/, + fences: noopTest, // fences not supported + paragraph: edit(block.normal._paragraph) + .replace("hr", block.hr) + .replace("heading", " *#{1,6} *[^\n]") + .replace("lheading", block.lheading) + .replace("blockquote", " {0,3}>") + .replace("|fences", "") + .replace("|list", "") + .replace("|html", "") + .getRegex(), +}) + +/** + * Inline-Level Grammar + */ +const inline = { + escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, + autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, + url: noopTest, + tag: + "^comment" + + "|^" + // self-closing tag + "|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>" + // open tag + "|^<\\?[\\s\\S]*?\\?>" + // processing instruction, e.g. + "|^" + // declaration, e.g. + "|^", // CDATA section + link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, + reflink: /^!?\[(label)\]\[(ref)\]/, + nolink: /^!?\[(ref)\](?:\[\])?/, + reflinkSearch: "reflink|nolink(?!\\()", + emStrong: { + lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, + // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. + // () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a + rDelimAst: + /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, + rDelimUnd: + /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/, // ^- Not allowed for _ + }, + code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, + br: /^( {2,}|\\)\n(?!\s*$)/, + del: noopTest, + text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~" +inline.punctuation = edit(inline.punctuation) + .replace(/punctuation/g, inline._punctuation) + .getRegex() + +// sequences em should skip over [title](link), `code`, +inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g +inline.escapedEmSt = /\\\*|\\_/g + +inline._comment = edit(block._comment).replace("(?:-->|$)", "-->").getRegex() + +inline.emStrong.lDelim = edit(inline.emStrong.lDelim) + .replace(/punct/g, inline._punctuation) + .getRegex() + +inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, "g") + .replace(/punct/g, inline._punctuation) + .getRegex() + +inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, "g") + .replace(/punct/g, inline._punctuation) + .getRegex() + +inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g + +inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/ +inline._email = + /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/ +inline.autolink = edit(inline.autolink) + .replace("scheme", inline._scheme) + .replace("email", inline._email) + .getRegex() + +inline._attribute = + /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/ + +inline.tag = edit(inline.tag) + .replace("comment", inline._comment) + .replace("attribute", inline._attribute) + .getRegex() + +inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/ +inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/ +inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/ + +inline.link = edit(inline.link) + .replace("label", inline._label) + .replace("href", inline._href) + .replace("title", inline._title) + .getRegex() + +inline.reflink = edit(inline.reflink) + .replace("label", inline._label) + .replace("ref", block._label) + .getRegex() + +inline.nolink = edit(inline.nolink).replace("ref", block._label).getRegex() + +inline.reflinkSearch = edit(inline.reflinkSearch, "g") + .replace("reflink", inline.reflink) + .replace("nolink", inline.nolink) + .getRegex() + +/** + * Normal Inline Grammar + */ + +inline.normal = merge({}, inline) + +/** + * Pedantic Inline Grammar + */ + +inline.pedantic = merge({}, inline.normal, { + strong: { + start: /^__|\*\*/, + middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + endAst: /\*\*(?!\*)/g, + endUnd: /__(?!_)/g, + }, + em: { + start: /^_|\*/, + middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, + endAst: /\*(?!\*)/g, + endUnd: /_(?!_)/g, + }, + link: edit(/^!?\[(label)\]\((.*?)\)/) + .replace("label", inline._label) + .getRegex(), + reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/) + .replace("label", inline._label) + .getRegex(), +}) + +/** + * GFM Inline Grammar + */ + +inline.gfm = merge({}, inline.normal, { + escape: edit(inline.escape).replace("])", "~|])").getRegex(), + _extended_email: + /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, + url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, + _backpedal: + /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/, + del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, + text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ 0.5) { + ch = "x" + ch.toString(16) + } + out += "&#" + ch + ";" + } + + return out +} + +/** + * Block Lexer + */ +class Lexer { + constructor(options) { + this.tokens = [] + this.tokens.links = Object.create(null) + this.options = options || defaults + this.options.tokenizer = this.options.tokenizer || new Tokenizer() + this.tokenizer = this.options.tokenizer + this.tokenizer.options = this.options + this.tokenizer.lexer = this + this.inlineQueue = [] + this.state = { + inLink: false, + inRawBlock: false, + top: true, + } + + const rules = { + block: block.normal, + inline: inline.normal, + } + + if (this.options.pedantic) { + rules.block = block.pedantic + rules.inline = inline.pedantic + } else if (this.options.gfm) { + rules.block = block.gfm + if (this.options.breaks) { + rules.inline = inline.breaks + } else { + rules.inline = inline.gfm + } + } + this.tokenizer.rules = rules + } + + /** + * Expose Rules + */ + static get rules() { + return { + block, + inline, + } + } + + /** + * Static Lex Method + */ + static lex(src, options) { + const lexer = new Lexer(options) + return lexer.lex(src) + } + + /** + * Static Lex Inline Method + */ + static lexInline(src, options) { + const lexer = new Lexer(options) + return lexer.inlineTokens(src) + } + + /** + * Preprocessing + */ + lex(src) { + src = src.replace(/\r\n|\r/g, "\n") + + this.blockTokens(src, this.tokens) + + let next + while ((next = this.inlineQueue.shift())) { + this.inlineTokens(next.src, next.tokens) + } + + return this.tokens + } + + /** + * Lexing + */ + blockTokens(src, tokens = []) { + if (this.options.pedantic) { + src = src.replace(/\t/g, " ").replace(/^ +$/gm, "") + } else { + src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => { + return leading + " ".repeat(tabs.length) + }) + } + + let token, lastToken, cutSrc, lastParagraphClipped + + while (src) { + if ( + this.options.extensions && + this.options.extensions.block && + this.options.extensions.block.some(extTokenizer => { + if ((token = extTokenizer.call({ lexer: this }, src, tokens))) { + src = src.substring(token.raw.length) + tokens.push(token) + return true + } + return false + }) + ) { + continue + } + + // newline + if ((token = this.tokenizer.space(src))) { + src = src.substring(token.raw.length) + if (token.raw.length === 1 && tokens.length > 0) { + // if there's a single \n as a spacer, it's terminating the last line, + // so move it there so that we don't get unecessary paragraph tags + tokens[tokens.length - 1].raw += "\n" + } else { + tokens.push(token) + } + continue + } + + // code + if ((token = this.tokenizer.code(src))) { + src = src.substring(token.raw.length) + lastToken = tokens[tokens.length - 1] + // An indented code block cannot interrupt a paragraph. + if ( + lastToken && + (lastToken.type === "paragraph" || lastToken.type === "text") + ) { + lastToken.raw += "\n" + token.raw + lastToken.text += "\n" + token.text + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text + } else { + tokens.push(token) + } + continue + } + + // fences + if ((token = this.tokenizer.fences(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // heading + if ((token = this.tokenizer.heading(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // hr + if ((token = this.tokenizer.hr(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // blockquote + if ((token = this.tokenizer.blockquote(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // list + if ((token = this.tokenizer.list(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // html + if ((token = this.tokenizer.html(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // def + if ((token = this.tokenizer.def(src))) { + src = src.substring(token.raw.length) + lastToken = tokens[tokens.length - 1] + if ( + lastToken && + (lastToken.type === "paragraph" || lastToken.type === "text") + ) { + lastToken.raw += "\n" + token.raw + lastToken.text += "\n" + token.raw + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text + } else if (!this.tokens.links[token.tag]) { + this.tokens.links[token.tag] = { + href: token.href, + title: token.title, + } + } + continue + } + + // table (gfm) + if ((token = this.tokenizer.table(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // lheading + if ((token = this.tokenizer.lheading(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // top-level paragraph + // prevent paragraph consuming extensions by clipping 'src' to extension start + cutSrc = src + if (this.options.extensions && this.options.extensions.startBlock) { + let startIndex = Infinity + const tempSrc = src.slice(1) + let tempStart + this.options.extensions.startBlock.forEach(function (getStartIndex) { + tempStart = getStartIndex.call({ lexer: this }, tempSrc) + if (typeof tempStart === "number" && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart) + } + }) + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1) + } + } + if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { + lastToken = tokens[tokens.length - 1] + if (lastParagraphClipped && lastToken.type === "paragraph") { + lastToken.raw += "\n" + token.raw + lastToken.text += "\n" + token.text + this.inlineQueue.pop() + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text + } else { + tokens.push(token) + } + lastParagraphClipped = cutSrc.length !== src.length + src = src.substring(token.raw.length) + continue + } + + // text + if ((token = this.tokenizer.text(src))) { + src = src.substring(token.raw.length) + lastToken = tokens[tokens.length - 1] + if (lastToken && lastToken.type === "text") { + lastToken.raw += "\n" + token.raw + lastToken.text += "\n" + token.text + this.inlineQueue.pop() + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text + } else { + tokens.push(token) + } + continue + } + + if (src) { + const errMsg = "Infinite loop on byte: " + src.charCodeAt(0) + if (this.options.silent) { + console.error(errMsg) + break + } else { + throw new Error(errMsg) + } + } + } + + this.state.top = true + return tokens + } + + inline(src, tokens) { + this.inlineQueue.push({ src, tokens }) + } + + /** + * Lexing/Compiling + */ + inlineTokens(src, tokens = []) { + let token, lastToken, cutSrc + + // String with links masked to avoid interference with em and strong + let maskedSrc = src + let match + let keepPrevChar, prevChar + + // Mask out reflinks + if (this.tokens.links) { + const links = Object.keys(this.tokens.links) + if (links.length > 0) { + while ( + (match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != + null + ) { + if ( + links.includes(match[0].slice(match[0].lastIndexOf("[") + 1, -1)) + ) { + maskedSrc = + maskedSrc.slice(0, match.index) + + "[" + + repeatString("a", match[0].length - 2) + + "]" + + maskedSrc.slice( + this.tokenizer.rules.inline.reflinkSearch.lastIndex + ) + } + } + } + } + // Mask out other blocks + while ( + (match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null + ) { + maskedSrc = + maskedSrc.slice(0, match.index) + + "[" + + repeatString("a", match[0].length - 2) + + "]" + + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex) + } + + // Mask out escaped em & strong delimiters + while ( + (match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null + ) { + maskedSrc = + maskedSrc.slice(0, match.index) + + "++" + + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex) + } + + while (src) { + if (!keepPrevChar) { + prevChar = "" + } + keepPrevChar = false + + // extensions + if ( + this.options.extensions && + this.options.extensions.inline && + this.options.extensions.inline.some(extTokenizer => { + if ((token = extTokenizer.call({ lexer: this }, src, tokens))) { + src = src.substring(token.raw.length) + tokens.push(token) + return true + } + return false + }) + ) { + continue + } + + // escape + if ((token = this.tokenizer.escape(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // tag + if ((token = this.tokenizer.tag(src))) { + src = src.substring(token.raw.length) + lastToken = tokens[tokens.length - 1] + if (lastToken && token.type === "text" && lastToken.type === "text") { + lastToken.raw += token.raw + lastToken.text += token.text + } else { + tokens.push(token) + } + continue + } + + // link + if ((token = this.tokenizer.link(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // reflink, nolink + if ((token = this.tokenizer.reflink(src, this.tokens.links))) { + src = src.substring(token.raw.length) + lastToken = tokens[tokens.length - 1] + if (lastToken && token.type === "text" && lastToken.type === "text") { + lastToken.raw += token.raw + lastToken.text += token.text + } else { + tokens.push(token) + } + continue + } + + // em & strong + if ((token = this.tokenizer.emStrong(src, maskedSrc, prevChar))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // code + if ((token = this.tokenizer.codespan(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // br + if ((token = this.tokenizer.br(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // del (gfm) + if ((token = this.tokenizer.del(src))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // autolink + if ((token = this.tokenizer.autolink(src, mangle))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // url (gfm) + if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) { + src = src.substring(token.raw.length) + tokens.push(token) + continue + } + + // text + // prevent inlineText consuming extensions by clipping 'src' to extension start + cutSrc = src + if (this.options.extensions && this.options.extensions.startInline) { + let startIndex = Infinity + const tempSrc = src.slice(1) + let tempStart + this.options.extensions.startInline.forEach(function (getStartIndex) { + tempStart = getStartIndex.call({ lexer: this }, tempSrc) + if (typeof tempStart === "number" && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart) + } + }) + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1) + } + } + if ((token = this.tokenizer.inlineText(cutSrc, smartypants))) { + src = src.substring(token.raw.length) + if (token.raw.slice(-1) !== "_") { + // Track prevChar before string of ____ started + prevChar = token.raw.slice(-1) + } + keepPrevChar = true + lastToken = tokens[tokens.length - 1] + if (lastToken && lastToken.type === "text") { + lastToken.raw += token.raw + lastToken.text += token.text + } else { + tokens.push(token) + } + continue + } + + if (src) { + const errMsg = "Infinite loop on byte: " + src.charCodeAt(0) + if (this.options.silent) { + console.error(errMsg) + break + } else { + throw new Error(errMsg) + } + } + } + + return tokens + } +} + +/** + * Renderer + */ +class Renderer { + constructor(options) { + this.options = options || defaults + } + + code(code, infostring, escaped) { + const lang = (infostring || "").match(/\S*/)[0] + if (this.options.highlight) { + const out = this.options.highlight(code, lang) + if (out != null && out !== code) { + escaped = true + code = out + } + } + + code = code.replace(/\n$/, "") + "\n" + + if (!lang) { + return ( + "
" +
+        (escaped ? code : escape(code, true)) +
+        "
\n" + ) + } + + return ( + '
' +
+      (escaped ? code : escape(code, true)) +
+      "
\n" + ) + } + + /** + * @param {string} quote + */ + blockquote(quote) { + return `
\n${quote}
\n` + } + + html(html) { + return html + } + + /** + * @param {string} text + * @param {string} level + * @param {string} raw + * @param {any} slugger + */ + heading(text, level, raw, slugger) { + if (this.options.headerIds) { + const id = this.options.headerPrefix + slugger.slug(raw) + return `${text}\n` + } + + // ignore IDs + return `${text}\n` + } + + hr() { + return this.options.xhtml ? "
\n" : "
\n" + } + + list(body, ordered, start) { + const type = ordered ? "ol" : "ul", + startatt = ordered && start !== 1 ? ' start="' + start + '"' : "" + return "<" + type + startatt + ">\n" + body + "\n" + } + + /** + * @param {string} text + */ + listitem(text) { + return `
  • ${text}
  • \n` + } + + checkbox(checked) { + return ( + " " + ) + } + + /** + * @param {string} text + */ + paragraph(text) { + return `

    ${text}

    \n` + } + + /** + * @param {string} header + * @param {string} body + */ + table(header, body) { + if (body) body = `${body}` + + return ( + "\n" + "\n" + header + "\n" + body + "
    \n" + ) + } + + /** + * @param {string} content + */ + tablerow(content) { + return `\n${content}\n` + } + + tablecell(content, flags) { + const type = flags.header ? "th" : "td" + const tag = flags.align ? `<${type} align="${flags.align}">` : `<${type}>` + return tag + content + `\n` + } + + /** + * span level renderer + * @param {string} text + */ + strong(text) { + return `${text}` + } + + /** + * @param {string} text + */ + em(text) { + return `${text}` + } + + /** + * @param {string} text + */ + codespan(text) { + return `${text}` + } + + br() { + return this.options.xhtml ? "
    " : "
    " + } + + /** + * @param {string} text + */ + del(text) { + return `${text}` + } + + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + link(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href) + if (href === null) { + return text + } + let out = '
    " + return out + } + + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + image(href, title, text) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href) + if (href === null) { + return text + } + + let out = `${text}" : ">" + return out + } + + text(text) { + return text + } +} + +/** + * TextRenderer + * returns only the textual part of the token + */ +class TextRenderer { + // no need for block level renderers + strong(text) { + return text + } + + em(text) { + return text + } + + codespan(text) { + return text + } + + del(text) { + return text + } + + html(text) { + return text + } + + text(text) { + return text + } + + link(href, title, text) { + return "" + text + } + + image(href, title, text) { + return "" + text + } + + br() { + return "" + } +} + +/** + * Slugger generates header id + */ +class Slugger { + constructor() { + this.seen = {} + } + + /** + * @param {string} value + */ + serialize(value) { + return ( + value + .toLowerCase() + .trim() + // remove html tags + .replace(/<[!\/a-z].*?>/gi, "") + // remove unwanted chars + .replace( + /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, + "" + ) + .replace(/\s/g, "-") + ) + } + + /** + * Finds the next safe (unique) slug to use + * @param {string} originalSlug + * @param {boolean} isDryRun + */ + getNextSafeSlug(originalSlug, isDryRun) { + let slug = originalSlug + let occurenceAccumulator = 0 + if (this.seen.hasOwnProperty(slug)) { + occurenceAccumulator = this.seen[originalSlug] + do { + occurenceAccumulator++ + slug = originalSlug + "-" + occurenceAccumulator + } while (this.seen.hasOwnProperty(slug)) + } + if (!isDryRun) { + this.seen[originalSlug] = occurenceAccumulator + this.seen[slug] = 0 + } + return slug + } + + /** + * Convert string to unique id + * @param {object} [options] + * @param {boolean} [options.dryrun] Generates the next unique slug without + * updating the internal accumulator. + */ + slug(value, options = {}) { + const slug = this.serialize(value) + return this.getNextSafeSlug(slug, options.dryrun) + } +} + +/** + * Parsing & Compiling + */ +class Parser { + constructor(options) { + this.options = options || defaults + this.options.renderer = this.options.renderer || new Renderer() + this.renderer = this.options.renderer + this.renderer.options = this.options + this.textRenderer = new TextRenderer() + this.slugger = new Slugger() + } + + /** + * Static Parse Method + */ + static parse(tokens, options) { + const parser = new Parser(options) + return parser.parse(tokens) + } + + /** + * Static Parse Inline Method + */ + static parseInline(tokens, options) { + const parser = new Parser(options) + return parser.parseInline(tokens) + } + + /** + * Parse Loop + */ + parse(tokens, top = true) { + let out = "", + i, + j, + k, + l2, + l3, + row, + cell, + header, + body, + token, + ordered, + start, + loose, + itemBody, + item, + checked, + task, + checkbox, + ret + + const l = tokens.length + for (i = 0; i < l; i++) { + token = tokens[i] + + // Run any renderer extensions + if ( + this.options.extensions && + this.options.extensions.renderers && + this.options.extensions.renderers[token.type] + ) { + ret = this.options.extensions.renderers[token.type].call( + { parser: this }, + token + ) + if ( + ret !== false || + ![ + "space", + "hr", + "heading", + "code", + "table", + "blockquote", + "list", + "html", + "paragraph", + "text", + ].includes(token.type) + ) { + out += ret || "" + continue + } + } + + switch (token.type) { + case "space": { + continue + } + case "hr": { + out += this.renderer.hr() + continue + } + case "heading": { + out += this.renderer.heading( + this.parseInline(token.tokens), + token.depth, + unescape(this.parseInline(token.tokens, this.textRenderer)), + this.slugger + ) + continue + } + case "code": { + out += this.renderer.code(token.text, token.lang, token.escaped) + continue + } + case "table": { + header = "" + + // header + cell = "" + l2 = token.header.length + for (j = 0; j < l2; j++) { + cell += this.renderer.tablecell( + this.parseInline(token.header[j].tokens), + { header: true, align: token.align[j] } + ) + } + header += this.renderer.tablerow(cell) + + body = "" + l2 = token.rows.length + for (j = 0; j < l2; j++) { + row = token.rows[j] + + cell = "" + l3 = row.length + for (k = 0; k < l3; k++) { + cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { + header: false, + align: token.align[k], + }) + } + + body += this.renderer.tablerow(cell) + } + out += this.renderer.table(header, body) + continue + } + case "blockquote": { + body = this.parse(token.tokens) + out += this.renderer.blockquote(body) + continue + } + case "list": { + ordered = token.ordered + start = token.start + loose = token.loose + l2 = token.items.length + + body = "" + for (j = 0; j < l2; j++) { + item = token.items[j] + checked = item.checked + task = item.task + + itemBody = "" + if (item.task) { + checkbox = this.renderer.checkbox(checked) + if (loose) { + if ( + item.tokens.length > 0 && + item.tokens[0].type === "paragraph" + ) { + item.tokens[0].text = checkbox + " " + item.tokens[0].text + if ( + item.tokens[0].tokens && + item.tokens[0].tokens.length > 0 && + item.tokens[0].tokens[0].type === "text" + ) { + item.tokens[0].tokens[0].text = + checkbox + " " + item.tokens[0].tokens[0].text + } + } else { + item.tokens.unshift({ + type: "text", + text: checkbox, + }) + } + } else { + itemBody += checkbox + } + } + + itemBody += this.parse(item.tokens, loose) + body += this.renderer.listitem(itemBody, task, checked) + } + + out += this.renderer.list(body, ordered, start) + continue + } + case "html": { + // TODO parse inline content if parameter markdown=1 + out += this.renderer.html(token.text) + continue + } + case "paragraph": { + out += this.renderer.paragraph(this.parseInline(token.tokens)) + continue + } + case "text": { + body = token.tokens ? this.parseInline(token.tokens) : token.text + while (i + 1 < l && tokens[i + 1].type === "text") { + token = tokens[++i] + body += + "\n" + + (token.tokens ? this.parseInline(token.tokens) : token.text) + } + out += top ? this.renderer.paragraph(body) : body + continue + } + + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.' + if (this.options.silent) { + console.error(errMsg) + return + } else { + throw new Error(errMsg) + } + } + } + } + + return out + } + + /** + * Parse Inline Tokens + */ + parseInline(tokens, renderer) { + renderer = renderer || this.renderer + let out = "", + i, + token, + ret + + const l = tokens.length + for (i = 0; i < l; i++) { + token = tokens[i] + + // Run any renderer extensions + if ( + this.options.extensions && + this.options.extensions.renderers && + this.options.extensions.renderers[token.type] + ) { + ret = this.options.extensions.renderers[token.type].call( + { parser: this }, + token + ) + if ( + ret !== false || + ![ + "escape", + "html", + "link", + "image", + "strong", + "em", + "codespan", + "br", + "del", + "text", + ].includes(token.type) + ) { + out += ret || "" + continue + } + } + + switch (token.type) { + case "escape": { + out += renderer.text(token.text) + break + } + case "html": { + out += renderer.html(token.text) + break + } + case "link": { + out += renderer.link( + token.href, + token.title, + this.parseInline(token.tokens, renderer) + ) + break + } + case "image": { + out += renderer.image(token.href, token.title, token.text) + break + } + case "strong": { + out += renderer.strong(this.parseInline(token.tokens, renderer)) + break + } + case "em": { + out += renderer.em(this.parseInline(token.tokens, renderer)) + break + } + case "codespan": { + out += renderer.codespan(token.text) + break + } + case "br": { + out += renderer.br() + break + } + case "del": { + out += renderer.del(this.parseInline(token.tokens, renderer)) + break + } + case "text": { + out += renderer.text(token.text) + break + } + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.' + if (this.options.silent) { + console.error(errMsg) + return + } else { + throw new Error(errMsg) + } + } + } + } + return out + } +} + +/** + * Marked + */ +function marked(src, opt, callback) { + // throw error in case of non string input + if (typeof src === "undefined" || src === null) { + throw new Error("marked(): input parameter is undefined or null") + } + if (typeof src !== "string") { + throw new Error( + "marked(): input parameter is of type " + + Object.prototype.toString.call(src) + + ", string expected" + ) + } + + if (typeof opt === "function") { + callback = opt + opt = null + } + + opt = merge({}, marked.defaults, opt || {}) + checkSanitizeDeprecation(opt) + + if (callback) { + const highlight = opt.highlight + let tokens + + try { + tokens = Lexer.lex(src, opt) + } catch (e) { + return callback(e) + } + + const done = function (err) { + let out + + if (!err) { + try { + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens) + } + out = Parser.parse(tokens, opt) + } catch (e) { + err = e + } + } + + opt.highlight = highlight + + return err ? callback(err) : callback(null, out) + } + + if (!highlight || highlight.length < 3) { + return done() + } + + delete opt.highlight + + if (!tokens.length) return done() + + let pending = 0 + marked.walkTokens(tokens, function (token) { + if (token.type === "code") { + pending++ + setTimeout(() => { + highlight(token.text, token.lang, function (err, code) { + if (err) { + return done(err) + } + if (code != null && code !== token.text) { + token.text = code + token.escaped = true + } + + pending-- + if (pending === 0) { + done() + } + }) + }, 0) + } + }) + + if (pending === 0) { + done() + } + + return + } + + try { + const tokens = Lexer.lex(src, opt) + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens) + } + return Parser.parse(tokens, opt) + } catch (e) { + e.message += "\nPlease report this to https://github.com/markedjs/marked." + if (opt.silent) { + return ( + "

    An error occurred:

    " +
    +        escape(e.message + "", true) +
    +        "
    " + ) + } + throw e + } +} + +/** + * Options + */ + +marked.options = marked.setOptions = function (opt) { + merge(marked.defaults, opt) + changeDefaults(marked.defaults) + return marked +} + +marked.getDefaults = getDefaults + +marked.defaults = defaults + +/** + * Use Extension + */ + +marked.use = function (...args) { + const opts = merge({}, ...args) + const extensions = marked.defaults.extensions || { + renderers: {}, + childTokens: {}, + } + let hasExtensions + + args.forEach(pack => { + // ==-- Parse "addon" extensions --== // + if (pack.extensions) { + hasExtensions = true + pack.extensions.forEach(ext => { + if (!ext.name) { + throw new Error("extension name required") + } + if (ext.renderer) { + // Renderer extensions + const prevRenderer = extensions.renderers + ? extensions.renderers[ext.name] + : null + if (prevRenderer) { + // Replace extension with func to run new extension but fall back if false + extensions.renderers[ext.name] = function (...args) { + let ret = ext.renderer.apply(this, args) + if (ret === false) { + ret = prevRenderer.apply(this, args) + } + return ret + } + } else { + extensions.renderers[ext.name] = ext.renderer + } + } + if (ext.tokenizer) { + // Tokenizer Extensions + if (!ext.level || (ext.level !== "block" && ext.level !== "inline")) { + throw new Error("extension level must be 'block' or 'inline'") + } + if (extensions[ext.level]) { + extensions[ext.level].unshift(ext.tokenizer) + } else { + extensions[ext.level] = [ext.tokenizer] + } + if (ext.start) { + // Function to check for start of token + if (ext.level === "block") { + if (extensions.startBlock) { + extensions.startBlock.push(ext.start) + } else { + extensions.startBlock = [ext.start] + } + } else if (ext.level === "inline") { + if (extensions.startInline) { + extensions.startInline.push(ext.start) + } else { + extensions.startInline = [ext.start] + } + } + } + } + if (ext.childTokens) { + // Child tokens to be visited by walkTokens + extensions.childTokens[ext.name] = ext.childTokens + } + }) + } + + // ==-- Parse "overwrite" extensions --== // + if (pack.renderer) { + const renderer = marked.defaults.renderer || new Renderer() + for (const prop in pack.renderer) { + const prevRenderer = renderer[prop] + // Replace renderer with func to run extension, but fall back if false + renderer[prop] = (...args) => { + let ret = pack.renderer[prop].apply(renderer, args) + if (ret === false) { + ret = prevRenderer.apply(renderer, args) + } + return ret + } + } + opts.renderer = renderer + } + if (pack.tokenizer) { + const tokenizer = marked.defaults.tokenizer || new Tokenizer() + for (const prop in pack.tokenizer) { + const prevTokenizer = tokenizer[prop] + // Replace tokenizer with func to run extension, but fall back if false + tokenizer[prop] = (...args) => { + let ret = pack.tokenizer[prop].apply(tokenizer, args) + if (ret === false) { + ret = prevTokenizer.apply(tokenizer, args) + } + return ret + } + } + opts.tokenizer = tokenizer + } + + // ==-- Parse WalkTokens extensions --== // + if (pack.walkTokens) { + const walkTokens = marked.defaults.walkTokens + opts.walkTokens = function (token) { + pack.walkTokens.call(this, token) + if (walkTokens) { + walkTokens.call(this, token) + } + } + } + + if (hasExtensions) { + opts.extensions = extensions + } + + marked.setOptions(opts) + }) +} + +/** + * Run callback for every token + */ + +marked.walkTokens = function (tokens, callback) { + for (const token of tokens) { + callback.call(marked, token) + switch (token.type) { + case "table": { + for (const cell of token.header) { + marked.walkTokens(cell.tokens, callback) + } + for (const row of token.rows) { + for (const cell of row) { + marked.walkTokens(cell.tokens, callback) + } + } + break + } + case "list": { + marked.walkTokens(token.items, callback) + break + } + default: { + if ( + marked.defaults.extensions && + marked.defaults.extensions.childTokens && + marked.defaults.extensions.childTokens[token.type] + ) { + // Walk any extensions + marked.defaults.extensions.childTokens[token.type].forEach(function ( + childTokens + ) { + marked.walkTokens(token[childTokens], callback) + }) + } else if (token.tokens) { + marked.walkTokens(token.tokens, callback) + } + } + } + } +} + +/** + * Parse Inline + * @param {string} src + */ +marked.parseInline = function (src, opt) { + // throw error in case of non string input + if (typeof src === "undefined" || src === null) { + throw new Error( + "marked.parseInline(): input parameter is undefined or null" + ) + } + if (typeof src !== "string") { + throw new Error( + "marked.parseInline(): input parameter is of type " + + Object.prototype.toString.call(src) + + ", string expected" + ) + } + + opt = merge({}, marked.defaults, opt || {}) + checkSanitizeDeprecation(opt) + + try { + const tokens = Lexer.lexInline(src, opt) + if (opt.walkTokens) { + marked.walkTokens(tokens, opt.walkTokens) + } + return Parser.parseInline(tokens, opt) + } catch (e) { + e.message += "\nPlease report this to https://github.com/markedjs/marked." + if (opt.silent) { + return ( + "

    An error occurred:

    " +
    +        escape(e.message + "", true) +
    +        "
    " + ) + } + throw e + } +} + +/** + * Expose + */ +marked.Parser = Parser +marked.parser = Parser.parse +marked.Renderer = Renderer +marked.TextRenderer = TextRenderer +marked.Lexer = Lexer +marked.lexer = Lexer.lex +marked.Tokenizer = Tokenizer +marked.Slugger = Slugger +marked.parse = marked + +const options = marked.options +const setOptions = marked.setOptions +const use = marked.use +const walkTokens = marked.walkTokens +const parseInline = marked.parseInline +const parse = marked +const parser = Parser.parse +const lexer = Lexer.lex + +const email = trigger.row +return marked(email.Message) From 43a284283367d78726d3fd43f252eaa5ea085270 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 21:04:33 +0100 Subject: [PATCH 082/213] Fix defaulting values --- packages/server/src/jsRunner/vm/isolated-vm.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/server/src/jsRunner/vm/isolated-vm.ts b/packages/server/src/jsRunner/vm/isolated-vm.ts index 12559df0b7..83a7646cfa 100644 --- a/packages/server/src/jsRunner/vm/isolated-vm.ts +++ b/packages/server/src/jsRunner/vm/isolated-vm.ts @@ -38,10 +38,9 @@ export class IsolatedVM implements VM { invocationTimeout?: number isolateAccumulatedTimeout?: number } = {}) { - memoryLimit = memoryLimit || environment.JS_RUNNER_MEMORY_LIMIT - invocationTimeout = memoryLimit || 1000 - - this.isolate = new ivm.Isolate({ memoryLimit }) + this.isolate = new ivm.Isolate({ + memoryLimit: memoryLimit || environment.JS_RUNNER_MEMORY_LIMIT, + }) this.vm = this.isolate.createContextSync() this.jail = this.vm.global this.jail.setSync("global", this.jail.derefInto()) @@ -51,7 +50,7 @@ export class IsolatedVM implements VM { [this.resultKey]: { [this.runResultKey]: "" }, }) - this.invocationTimeout = invocationTimeout + this.invocationTimeout = invocationTimeout || 1000 this.isolateAccumulatedTimeout = isolateAccumulatedTimeout } From d1e0b37dc21313a65187387afc7d549ef238b539 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 19 Feb 2024 21:07:45 +0100 Subject: [PATCH 083/213] Remove magic number --- packages/server/src/jsRunner/vm/isolated-vm.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/server/src/jsRunner/vm/isolated-vm.ts b/packages/server/src/jsRunner/vm/isolated-vm.ts index 83a7646cfa..f431ff644b 100644 --- a/packages/server/src/jsRunner/vm/isolated-vm.ts +++ b/packages/server/src/jsRunner/vm/isolated-vm.ts @@ -50,7 +50,8 @@ export class IsolatedVM implements VM { [this.resultKey]: { [this.runResultKey]: "" }, }) - this.invocationTimeout = invocationTimeout || 1000 + this.invocationTimeout = + invocationTimeout || environment.JS_PER_INVOCATION_TIMEOUT_MS this.isolateAccumulatedTimeout = isolateAccumulatedTimeout } From 634bf5f8ba7851d58dd8781dc0b124b45bfcb48e Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Mon, 19 Feb 2024 20:26:23 +0000 Subject: [PATCH 084/213] Bump version to 2.20.0 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 62068e25a8..3386214dcf 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.19.6", + "version": "2.20.0", "npmClient": "yarn", "packages": [ "packages/*", From 335228e8782f9a9e7044c9869250c05d1c2817ba Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Mon, 19 Feb 2024 21:08:26 +0000 Subject: [PATCH 085/213] isolated VM test cases. --- .../src/jsRunner/tests/isolatedVM.spec.ts | 53 +++++++++++++++++++ .../src/jsRunner/tests/jsRunner.spec.ts | 21 ++++++++ 2 files changed, 74 insertions(+) diff --git a/packages/server/src/jsRunner/tests/isolatedVM.spec.ts b/packages/server/src/jsRunner/tests/isolatedVM.spec.ts index 0bd400c8d7..fd26246de5 100644 --- a/packages/server/src/jsRunner/tests/isolatedVM.spec.ts +++ b/packages/server/src/jsRunner/tests/isolatedVM.spec.ts @@ -30,4 +30,57 @@ describe("Test isolated vm directly", () => { }) expect(result).toBe("

    dddd

    \n") }) + + it("handle a mapping case", async () => { + const context = { + data: { + data: { + searchProducts: { + results: [ + { imageLinks: ["_S/"] } + ] + } + } + } + } + const result = await compare(` + const dataUnnested = data.data.searchProducts.results + const emptyLink = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRC3hpq0MXqXssA28Lm5NrzcOYAyr--q3xyg&usqp=CAU" + let pImage = emptyLink + let sImage = emptyLink + let uImage = emptyLink + let lImage = emptyLink + let b1Image = emptyLink + let b2Image = emptyLink + + const dataTransformed = dataUnnested.map(x=> { + let imageLinks = x.imageLinks + for (let i = 0; i < imageLinks.length; i++){ + if(imageLinks[i].includes("_P/") || imageLinks[i].includes("_p/")){ + pImage = imageLinks[i] + } else if (imageLinks[i].includes("_S/") || imageLinks[i].includes("_s/")){ + sImage = imageLinks[i] + } else if (imageLinks[i].includes("_U/") || imageLinks[i].includes("_u/")){ + uImage = imageLinks[i] + } else if (imageLinks[i].includes("_L/") || imageLinks[i].includes("_l/")){ + lImage = imageLinks[i] + } else if (imageLinks[i].includes("_B/") || imageLinks[i].includes("_b/")){ + b1Image = imageLinks[i] + } else if (imageLinks[i].includes("_B2/") || imageLinks[i].includes("_b2/")){ + b2Image = imageLinks[i] + } + } + + const arrangedLinks = [pImage, sImage, uImage, lImage, b1Image, b2Image] + x.imageLinks = arrangedLinks + + return x + }) + + return dataTransformed + `, context) + expect(result).toBeDefined() + expect(result.length).toBe(1) + expect(result[0].imageLinks.length).toBe(6) + }) }) diff --git a/packages/server/src/jsRunner/tests/jsRunner.spec.ts b/packages/server/src/jsRunner/tests/jsRunner.spec.ts index 9bb9052eda..6dc6fd0887 100644 --- a/packages/server/src/jsRunner/tests/jsRunner.spec.ts +++ b/packages/server/src/jsRunner/tests/jsRunner.spec.ts @@ -144,5 +144,26 @@ describe("jsRunner (using isolated-vm)", () => { expect(result).toBeDefined() expect(result).toBe(3) }) + + it("should handle test case 4", async () => { + const context = { + "Time Sheets": ["a", "b"] + } + const result = await processJS(` + let hours = 0 + if (($("[Time Sheets]") != null) == true){ + for (i = 0; i < $("[Time Sheets]").length; i++){ + let hoursLogged = "Time Sheets." + i + ".Hours" + hours += $(hoursLogged) + } + return hours + } + if (($("[Time Sheets]") != null) == false){ + return hours + } + `, context) + expect(result).toBeDefined() + expect(result).toBe("0ab") + }) }) }) From f99dbeb2ffe5457a71421ec9c9c3f719750a1f05 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 19 Feb 2024 18:28:43 -0300 Subject: [PATCH 086/213] update pro submodule --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index aaf7101cd1..32e4d4f946 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit aaf7101cd1493215155cc8f83124c70d53eb1be4 +Subproject commit 32e4d4f946c881bd87777d99b17f13ca4a38ea99 From 9443a113ecb4b098b38898105d6f0eaeed0d24e3 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 19 Feb 2024 18:44:58 -0300 Subject: [PATCH 087/213] update reference --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index 32e4d4f946..7bc9f00fac 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit 32e4d4f946c881bd87777d99b17f13ca4a38ea99 +Subproject commit 7bc9f00fac37571b45ca41a034004860bf058cb3 From 2d019ccb6573a89353777de5dd02d26a7b2a551c Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 19 Feb 2024 18:46:13 -0300 Subject: [PATCH 088/213] account portal submodule --- packages/account-portal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/account-portal b/packages/account-portal index cc12291732..8c446c4ba3 160000 --- a/packages/account-portal +++ b/packages/account-portal @@ -1 +1 @@ -Subproject commit cc12291732ee902dc832bc7d93cf2086ffdf0cff +Subproject commit 8c446c4ba385592127fa31755d3b64467b291882 From fcea092667dd4a66de371ca4170a0405a64b7e5d Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 20 Feb 2024 09:30:53 +0000 Subject: [PATCH 089/213] Remove link. --- packages/server/src/jsRunner/tests/isolatedVM.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/jsRunner/tests/isolatedVM.spec.ts b/packages/server/src/jsRunner/tests/isolatedVM.spec.ts index fd26246de5..bd74940dd6 100644 --- a/packages/server/src/jsRunner/tests/isolatedVM.spec.ts +++ b/packages/server/src/jsRunner/tests/isolatedVM.spec.ts @@ -45,7 +45,7 @@ describe("Test isolated vm directly", () => { } const result = await compare(` const dataUnnested = data.data.searchProducts.results - const emptyLink = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRC3hpq0MXqXssA28Lm5NrzcOYAyr--q3xyg&usqp=CAU" + const emptyLink = "https://budibase.com" let pImage = emptyLink let sImage = emptyLink let uImage = emptyLink From 93b18b81e003da221cb065d9587f0a6ed337fbfb Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 20 Feb 2024 10:49:45 +0000 Subject: [PATCH 090/213] Fix re-used context in JS runner. --- packages/server/src/api/controllers/script.ts | 7 ++++--- packages/server/src/jsRunner/index.ts | 15 +++++-------- .../server/src/jsRunner/vm/isolated-vm.ts | 14 +++++++++++-- packages/server/src/jsRunner/vm/vm2.ts | 14 +++++++++++-- packages/server/src/threads/query.ts | 21 ++++++++----------- packages/types/src/sdk/vm.ts | 1 + 6 files changed, 43 insertions(+), 29 deletions(-) diff --git a/packages/server/src/api/controllers/script.ts b/packages/server/src/api/controllers/script.ts index bdca2d6e18..93e1ad7df9 100644 --- a/packages/server/src/api/controllers/script.ts +++ b/packages/server/src/api/controllers/script.ts @@ -3,9 +3,10 @@ import { IsolatedVM } from "../../jsRunner/vm" export async function execute(ctx: Ctx) { const { script, context } = ctx.request.body - const runner = new IsolatedVM().withContext(context) - - const result = runner.execute(`(function(){\n${script}\n})();`) + const vm = new IsolatedVM() + const result = vm.withContext(context, () => + vm.execute(`(function(){\n${script}\n})();`) + ) ctx.body = result } diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index 3c13aef1d4..1e8bee04c3 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -23,22 +23,17 @@ export function init() { try { const bbCtx = context.getCurrentContext()! - let { vm } = bbCtx - if (!vm) { - // Can't copy the native helpers into the isolate. We just ignore them as they are handled properly from the helpersSource - const { helpers, ...ctxToPass } = ctx - - vm = new IsolatedVM({ + if (!bbCtx.vm) { + const vm = new IsolatedVM({ memoryLimit: env.JS_RUNNER_MEMORY_LIMIT, invocationTimeout: env.JS_PER_INVOCATION_TIMEOUT_MS, isolateAccumulatedTimeout: env.JS_PER_REQUEST_TIMEOUT_MS, - }) - .withContext(ctxToPass) - .withHelpers() + }).withHelpers() bbCtx.vm = vm } - return vm.execute(js) + const { helpers, ...rest } = ctx + return bbCtx.vm.withContext(rest, () => bbCtx.vm!.execute(js)) } catch (error: any) { if (error.message === "Script execution timed out.") { throw new JsErrorTimeout() diff --git a/packages/server/src/jsRunner/vm/isolated-vm.ts b/packages/server/src/jsRunner/vm/isolated-vm.ts index f431ff644b..78250acdd2 100644 --- a/packages/server/src/jsRunner/vm/isolated-vm.ts +++ b/packages/server/src/jsRunner/vm/isolated-vm.ts @@ -97,10 +97,14 @@ export class IsolatedVM implements VM { return this } - withContext(context: Record) { + withContext(context: Record, f: () => T) { this.addToContext(context) - return this + try { + return f() + } finally { + this.removeFromContext(Object.keys(context)) + } } withParsingBson(data: any) { @@ -224,6 +228,12 @@ export class IsolatedVM implements VM { } } + private removeFromContext(keys: string[]) { + for (let key of keys) { + this.jail.deleteSync(key) + } + } + private getFromContext(key: string) { const ref = this.vm.global.getSync(key, { reference: true }) const result = ref.copySync() diff --git a/packages/server/src/jsRunner/vm/vm2.ts b/packages/server/src/jsRunner/vm/vm2.ts index 6d05943d25..75e3899064 100644 --- a/packages/server/src/jsRunner/vm/vm2.ts +++ b/packages/server/src/jsRunner/vm/vm2.ts @@ -7,16 +7,26 @@ export class VM2 implements VM { vm: vm2.VM results: { out: string } - constructor(context: any) { + constructor() { this.vm = new vm2.VM({ timeout: JS_TIMEOUT_MS, }) this.results = { out: "" } - this.vm.setGlobals(context) this.vm.setGlobal("fetch", fetch) this.vm.setGlobal("results", this.results) } + withContext(context: Record, fn: () => T): T { + this.vm.setGlobals(context) + try { + return fn() + } finally { + for (const key in context) { + this.vm.setGlobal(key, undefined) + } + } + } + execute(script: string) { const code = `let fn = () => {\n${script}\n}; results.out = fn();` const vmScript = new vm2.VMScript(code) diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index c159f24268..6cc07c1256 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -131,24 +131,21 @@ class QueryRunner { if (transformer) { let runner: VM if (!USE_ISOLATED_VM) { - runner = new VM2({ - data: rows, - params: enrichedParameters, - }) + runner = new VM2() } else { transformer = `(function(){\n${transformer}\n})();` - let isolatedVm = new IsolatedVM().withContext({ - data: rows, - params: enrichedParameters, - }) + let vm = new IsolatedVM() if (datasource.source === SourceName.MONGODB) { - isolatedVm = isolatedVm.withParsingBson(rows) + vm = vm.withParsingBson(rows) } - - runner = isolatedVm + runner = vm } - rows = runner.execute(transformer) + const ctx = { + data: rows, + params: enrichedParameters, + } + rows = runner.withContext(ctx, () => runner.execute(transformer)) } // if the request fails we retry once, invalidating the cached value diff --git a/packages/types/src/sdk/vm.ts b/packages/types/src/sdk/vm.ts index 43b7775d3b..314883e0c5 100644 --- a/packages/types/src/sdk/vm.ts +++ b/packages/types/src/sdk/vm.ts @@ -1,3 +1,4 @@ export interface VM { execute(code: string): any + withContext(context: Record, fn: () => T): T } From cdad301e7e39fd3d0258a5c5b79802d0cd768143 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 20 Feb 2024 11:52:56 +0100 Subject: [PATCH 091/213] Undefined checks for context --- packages/server/src/jsRunner/index.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index 3c13aef1d4..5db461e023 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -21,9 +21,9 @@ export function init() { } try { - const bbCtx = context.getCurrentContext()! + const bbCtx = context.getCurrentContext() - let { vm } = bbCtx + let vm = bbCtx?.vm if (!vm) { // Can't copy the native helpers into the isolate. We just ignore them as they are handled properly from the helpersSource const { helpers, ...ctxToPass } = ctx @@ -36,7 +36,10 @@ export function init() { .withContext(ctxToPass) .withHelpers() - bbCtx.vm = vm + if (bbCtx) { + // If we have a context, we want to persist it to reuse the isolate + bbCtx.vm = vm + } } return vm.execute(js) } catch (error: any) { From a866677080bde9cbac804b306dc32d6798bd9e3e Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 20 Feb 2024 10:59:04 +0000 Subject: [PATCH 092/213] Add tests. --- .../server/src/api/routes/tests/row.spec.ts | 43 +++++++++++++++++++ packages/server/src/jsRunner/index.ts | 4 +- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index 10dac3c0ea..239da36351 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -2135,5 +2135,48 @@ describe.each([ } ) }) + + it("should not carry over context between formulas", async () => { + const js = Buffer.from(`return $("[text]");`).toString("base64") + const table = await config.createTable({ + name: "table", + type: "table", + schema: { + text: { + name: "text", + type: FieldType.STRING, + }, + formula: { + name: "formula", + type: FieldType.FORMULA, + formula: `{{ js "${js}"}}`, + formulaType: FormulaType.DYNAMIC, + }, + }, + }) + + for (let i = 0; i < 10; i++) { + await config.api.row.save(table._id!, { text: `foo${i}` }) + } + + const { rows } = await config.api.row.search(table._id!) + expect(rows).toHaveLength(10) + + const formulaValues = rows.map(r => r.formula) + expect(formulaValues).toEqual( + expect.arrayContaining([ + "foo0", + "foo1", + "foo2", + "foo3", + "foo4", + "foo5", + "foo6", + "foo7", + "foo8", + "foo9", + ]) + ) + }) }) }) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index 1e8bee04c3..d0385404fe 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -24,13 +24,11 @@ export function init() { const bbCtx = context.getCurrentContext()! if (!bbCtx.vm) { - const vm = new IsolatedVM({ + bbCtx.vm = new IsolatedVM({ memoryLimit: env.JS_RUNNER_MEMORY_LIMIT, invocationTimeout: env.JS_PER_INVOCATION_TIMEOUT_MS, isolateAccumulatedTimeout: env.JS_PER_REQUEST_TIMEOUT_MS, }).withHelpers() - - bbCtx.vm = vm } const { helpers, ...rest } = ctx return bbCtx.vm.withContext(rest, () => bbCtx.vm!.execute(js)) From 904476de5ca1b34a59edb3f85237daad2b0757fd Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 20 Feb 2024 11:04:03 +0000 Subject: [PATCH 093/213] Bump version to 2.20.1 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 3386214dcf..8210fbae99 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.20.0", + "version": "2.20.1", "npmClient": "yarn", "packages": [ "packages/*", From 285916d0bfbfe2f56e2d5c7365348ad0de2e40ff Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 20 Feb 2024 11:11:27 +0000 Subject: [PATCH 094/213] Some PR comments/build issue. --- packages/server/src/jsRunner/vm/builtin-vm.ts | 11 +++++++++++ packages/server/src/jsRunner/vm/isolated-vm.ts | 4 ++-- packages/server/src/jsRunner/vm/vm2.ts | 4 ++-- packages/types/src/sdk/vm.ts | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/server/src/jsRunner/vm/builtin-vm.ts b/packages/server/src/jsRunner/vm/builtin-vm.ts index b4c9f775f9..849abdd6f2 100644 --- a/packages/server/src/jsRunner/vm/builtin-vm.ts +++ b/packages/server/src/jsRunner/vm/builtin-vm.ts @@ -15,6 +15,17 @@ export class BuiltInVM implements VM { this.span = span } + withContext(context: Record, executeWithContext: () => T): T { + this.ctx = vm.createContext(context) + try { + return executeWithContext() + } finally { + for (const key in context) { + delete this.ctx[key] + } + } + } + execute(code: string) { const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS let track: TrackerFn = f => f() diff --git a/packages/server/src/jsRunner/vm/isolated-vm.ts b/packages/server/src/jsRunner/vm/isolated-vm.ts index 78250acdd2..e5c431666d 100644 --- a/packages/server/src/jsRunner/vm/isolated-vm.ts +++ b/packages/server/src/jsRunner/vm/isolated-vm.ts @@ -97,11 +97,11 @@ export class IsolatedVM implements VM { return this } - withContext(context: Record, f: () => T) { + withContext(context: Record, executeWithContext: () => T) { this.addToContext(context) try { - return f() + return executeWithContext() } finally { this.removeFromContext(Object.keys(context)) } diff --git a/packages/server/src/jsRunner/vm/vm2.ts b/packages/server/src/jsRunner/vm/vm2.ts index 75e3899064..5825025d26 100644 --- a/packages/server/src/jsRunner/vm/vm2.ts +++ b/packages/server/src/jsRunner/vm/vm2.ts @@ -16,10 +16,10 @@ export class VM2 implements VM { this.vm.setGlobal("results", this.results) } - withContext(context: Record, fn: () => T): T { + withContext(context: Record, executeWithContext: () => T): T { this.vm.setGlobals(context) try { - return fn() + return executeWithContext() } finally { for (const key in context) { this.vm.setGlobal(key, undefined) diff --git a/packages/types/src/sdk/vm.ts b/packages/types/src/sdk/vm.ts index 314883e0c5..f1099524bc 100644 --- a/packages/types/src/sdk/vm.ts +++ b/packages/types/src/sdk/vm.ts @@ -1,4 +1,4 @@ export interface VM { execute(code: string): any - withContext(context: Record, fn: () => T): T + withContext(context: Record, executeWithContext: () => T): T } From b7190f458d15ad6d519e2752324cd63c4cb0ac05 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 20 Feb 2024 12:26:10 +0100 Subject: [PATCH 095/213] Update pro ref --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index 7bc9f00fac..6f3a0b7f72 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit 7bc9f00fac37571b45ca41a034004860bf058cb3 +Subproject commit 6f3a0b7f72d16f9604179af98ff7602ca0df2737 From b9afe1b926dd420ca4d32d17e203d5b406346575 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 20 Feb 2024 12:09:54 +0100 Subject: [PATCH 096/213] Remove vm2 wrapper --- packages/server/src/jsRunner/vm/index.ts | 1 - packages/server/src/jsRunner/vm/vm2.ts | 36 ------------------------ packages/server/src/threads/query.ts | 22 +++++---------- 3 files changed, 7 insertions(+), 52 deletions(-) delete mode 100644 packages/server/src/jsRunner/vm/vm2.ts diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index 01e0daa354..cc50a5eeaa 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -1,3 +1,2 @@ export * from "./isolated-vm" export * from "./builtin-vm" -export * from "./vm2" diff --git a/packages/server/src/jsRunner/vm/vm2.ts b/packages/server/src/jsRunner/vm/vm2.ts deleted file mode 100644 index 5825025d26..0000000000 --- a/packages/server/src/jsRunner/vm/vm2.ts +++ /dev/null @@ -1,36 +0,0 @@ -import vm2 from "vm2" -import { VM } from "@budibase/types" - -const JS_TIMEOUT_MS = 1000 - -export class VM2 implements VM { - vm: vm2.VM - results: { out: string } - - constructor() { - this.vm = new vm2.VM({ - timeout: JS_TIMEOUT_MS, - }) - this.results = { out: "" } - this.vm.setGlobal("fetch", fetch) - this.vm.setGlobal("results", this.results) - } - - withContext(context: Record, executeWithContext: () => T): T { - this.vm.setGlobals(context) - try { - return executeWithContext() - } finally { - for (const key in context) { - this.vm.setGlobal(key, undefined) - } - } - } - - execute(script: string) { - const code = `let fn = () => {\n${script}\n}; results.out = fn();` - const vmScript = new vm2.VMScript(code) - this.vm.run(vmScript) - return this.results.out - } -} diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index 6cc07c1256..9366f2b12c 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -7,20 +7,18 @@ import { QueryVariable, QueryResponse, } from "./definitions" -import { IsolatedVM, VM2 } from "../jsRunner/vm" +import { IsolatedVM } from "../jsRunner/vm" import { getIntegration } from "../integrations" import { processStringSync } from "@budibase/string-templates" import { context, cache, auth } from "@budibase/backend-core" import { getGlobalIDFromUserMetadataID } from "../db/utils" import sdk from "../sdk" import { cloneDeep } from "lodash/fp" -import { Datasource, Query, SourceName, VM } from "@budibase/types" +import { Datasource, Query, SourceName } from "@budibase/types" import { isSQL } from "../integrations/utils" import { interpolateSQL } from "../integrations/queries/sql" -const USE_ISOLATED_VM = true - class QueryRunner { datasource: Datasource queryVerb: string @@ -129,23 +127,17 @@ class QueryRunner { // transform as required if (transformer) { - let runner: VM - if (!USE_ISOLATED_VM) { - runner = new VM2() - } else { - transformer = `(function(){\n${transformer}\n})();` - let vm = new IsolatedVM() - if (datasource.source === SourceName.MONGODB) { - vm = vm.withParsingBson(rows) - } - runner = vm + transformer = `(function(){\n${transformer}\n})();` + let vm = new IsolatedVM() + if (datasource.source === SourceName.MONGODB) { + vm = vm.withParsingBson(rows) } const ctx = { data: rows, params: enrichedParameters, } - rows = runner.withContext(ctx, () => runner.execute(transformer)) + rows = vm.withContext(ctx, () => vm.execute(transformer)) } // if the request fails we retry once, invalidating the cached value From 73d39836ab480deb555ca162268625665224d69a Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 20 Feb 2024 12:10:49 +0100 Subject: [PATCH 097/213] Remove vm wrapper --- packages/server/src/jsRunner/index.ts | 9 +-- packages/server/src/jsRunner/vm/builtin-vm.ts | 76 ------------------- packages/server/src/jsRunner/vm/index.ts | 1 - 3 files changed, 1 insertion(+), 85 deletions(-) delete mode 100644 packages/server/src/jsRunner/vm/builtin-vm.ts diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index 3b6b464dae..0fbfed3b66 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -8,18 +8,11 @@ import { import { context, logging } from "@budibase/backend-core" import tracer from "dd-trace" -import { BuiltInVM, IsolatedVM } from "./vm" - -const USE_ISOLATED_VM = true +import { IsolatedVM } from "./vm" export function init() { setJSRunner((js: string, ctx: Record) => { return tracer.trace("runJS", {}, span => { - if (!USE_ISOLATED_VM) { - const vm = new BuiltInVM(ctx, span) - return vm.execute(js) - } - try { const bbCtx = context.getCurrentContext() diff --git a/packages/server/src/jsRunner/vm/builtin-vm.ts b/packages/server/src/jsRunner/vm/builtin-vm.ts deleted file mode 100644 index 849abdd6f2..0000000000 --- a/packages/server/src/jsRunner/vm/builtin-vm.ts +++ /dev/null @@ -1,76 +0,0 @@ -import vm from "vm" -import env from "../../environment" -import { context, timers } from "@budibase/backend-core" -import tracer, { Span } from "dd-trace" -import { VM } from "@budibase/types" - -type TrackerFn = (f: () => T) => T - -export class BuiltInVM implements VM { - private ctx: vm.Context - private span?: Span - - constructor(ctx: vm.Context, span?: Span) { - this.ctx = ctx - this.span = span - } - - withContext(context: Record, executeWithContext: () => T): T { - this.ctx = vm.createContext(context) - try { - return executeWithContext() - } finally { - for (const key in context) { - delete this.ctx[key] - } - } - } - - execute(code: string) { - const perRequestLimit = env.JS_PER_REQUEST_TIMEOUT_MS - let track: TrackerFn = f => f() - if (perRequestLimit) { - const bbCtx = tracer.trace("runJS.getCurrentContext", {}, span => - context.getCurrentContext() - ) - if (bbCtx) { - if (!bbCtx.jsExecutionTracker) { - this.span?.addTags({ - createdExecutionTracker: true, - }) - bbCtx.jsExecutionTracker = tracer.trace( - "runJS.createExecutionTimeTracker", - {}, - span => timers.ExecutionTimeTracker.withLimit(perRequestLimit) - ) - } - this.span?.addTags({ - js: { - limitMS: bbCtx.jsExecutionTracker.limitMs, - elapsedMS: bbCtx.jsExecutionTracker.elapsedMS, - }, - }) - // We call checkLimit() here to prevent paying the cost of creating - // a new VM context below when we don't need to. - tracer.trace("runJS.checkLimitAndBind", {}, span => { - bbCtx.jsExecutionTracker!.checkLimit() - track = bbCtx.jsExecutionTracker!.track.bind(bbCtx.jsExecutionTracker) - }) - } - } - - this.ctx = { - ...this.ctx, - alert: undefined, - setInterval: undefined, - setTimeout: undefined, - } - - vm.createContext(this.ctx) - return track(() => - vm.runInNewContext(code, this.ctx, { - timeout: env.JS_PER_INVOCATION_TIMEOUT_MS, - }) - ) - } -} diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index cc50a5eeaa..286a277cfb 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -1,2 +1 @@ export * from "./isolated-vm" -export * from "./builtin-vm" From 8480fb0227506d13f0306cc26cda2012270fd555 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 20 Feb 2024 12:11:26 +0100 Subject: [PATCH 098/213] Remove vm2 package --- packages/server/package.json | 1 - yarn.lock | 10 +--------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/server/package.json b/packages/server/package.json index 57e1a828b7..79daf1ba4b 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -114,7 +114,6 @@ "undici-types": "^6.0.1", "uuid": "^8.3.2", "validate.js": "0.13.1", - "vm2": "^3.9.19", "worker-farm": "1.7.0", "xml2js": "0.5.0" }, diff --git a/yarn.lock b/yarn.lock index 10acc829b3..47de6a67ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6463,7 +6463,7 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.1.0, acorn@^8.10.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.1.0, acorn@^8.10.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: version "8.11.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== @@ -21633,14 +21633,6 @@ vlq@^0.2.2: resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" integrity sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow== -vm2@^3.9.19: - version "3.9.19" - resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.19.tgz#be1e1d7a106122c6c492b4d51c2e8b93d3ed6a4a" - integrity sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg== - dependencies: - acorn "^8.7.0" - acorn-walk "^8.2.0" - vuvuzela@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/vuvuzela/-/vuvuzela-1.0.3.tgz#3be145e58271c73ca55279dd851f12a682114b0b" From f67173b757eb15204c6aff19d338c52e402d7a99 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 20 Feb 2024 11:35:29 +0000 Subject: [PATCH 099/213] Fix flaky table test. --- packages/server/src/api/routes/tests/table.spec.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index c8cb3ef21b..ce119e56f0 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -368,10 +368,12 @@ describe("/tables", () => { .set(config.defaultHeaders()) .expect("Content-Type", /json/) .expect(200) - const fetchedTable = res.body[0] - expect(fetchedTable.name).toEqual(testTable.name) - expect(fetchedTable.type).toEqual("table") - expect(fetchedTable.sourceType).toEqual("internal") + + const table = res.body.find((t: Table) => t._id === testTable._id) + expect(table).toBeDefined() + expect(table.name).toEqual(testTable.name) + expect(table.type).toEqual("table") + expect(table.sourceType).toEqual("internal") }) it("should apply authorization to endpoint", async () => { From 568f1547bc1a5844be78740a8d9bf2fb3658fa0c Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 20 Feb 2024 11:47:56 +0000 Subject: [PATCH 100/213] Bump version to 2.20.2 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 8210fbae99..04f5c6e880 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.20.1", + "version": "2.20.2", "npmClient": "yarn", "packages": [ "packages/*", From 9127337f8b41eacdd0650978ed7bc079e46e608e Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 20 Feb 2024 13:14:49 +0100 Subject: [PATCH 101/213] Use latest image --- hosting/single/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile index f89967cb0b..ee98b0729d 100644 --- a/hosting/single/Dockerfile +++ b/hosting/single/Dockerfile @@ -38,7 +38,7 @@ COPY packages/worker/pm2.config.js packages/worker/pm2.config.js COPY packages/string-templates packages/string-templates -FROM budibase/couchdb as runner +FROM budibase/couchdb:v3.3.3 as runner ARG TARGETARCH ENV TARGETARCH $TARGETARCH #TARGETBUILD can be set to single (for single docker image) or aas (for azure app service) From c7ec698d30d01051f8f16dcdbf9d73c06299f397 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 20 Feb 2024 12:20:35 +0000 Subject: [PATCH 102/213] Ensure a backup is complete before attempting to import it. --- packages/server/src/api/routes/tests/backup.spec.ts | 7 ++----- packages/server/src/tests/utilities/api/backup.ts | 13 +++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/server/src/api/routes/tests/backup.spec.ts b/packages/server/src/api/routes/tests/backup.spec.ts index d12b5e1507..acfac783db 100644 --- a/packages/server/src/api/routes/tests/backup.spec.ts +++ b/packages/server/src/api/routes/tests/backup.spec.ts @@ -8,7 +8,6 @@ import { mocks } from "@budibase/backend-core/tests" mocks.licenses.useBackups() describe("/backups", () => { - let request = setup.getRequest() let config = setup.getConfig() afterAll(setup.afterAll) @@ -59,10 +58,8 @@ describe("/backups", () => { await config.createScreen() const exportRes = await config.api.backup.createBackup(appId) expect(exportRes.backupId).toBeDefined() - const importRes = await config.api.backup.importBackup( - appId, - exportRes.backupId - ) + await config.api.backup.waitForBackupToComplete(appId, exportRes.backupId) + await config.api.backup.importBackup(appId, exportRes.backupId) }) }) diff --git a/packages/server/src/tests/utilities/api/backup.ts b/packages/server/src/tests/utilities/api/backup.ts index f9cbc7086e..8cd1e58a29 100644 --- a/packages/server/src/tests/utilities/api/backup.ts +++ b/packages/server/src/tests/utilities/api/backup.ts @@ -31,6 +31,19 @@ export class BackupAPI extends TestAPI { return result.body as CreateAppBackupResponse } + waitForBackupToComplete = async (appId: string, backupId: string) => { + for (let i = 0; i < 10; i++) { + await new Promise(resolve => setTimeout(resolve, 1000)) + const result = await this.request + .get(`/api/apps/${appId}/backups/${backupId}/file`) + .set(this.config.defaultHeaders()) + if (result.status === 200) { + return + } + } + throw new Error("Backup did not complete") + } + importBackup = async ( appId: string, backupId: string From e8d38b17d9b68f7a7263708d6000f6f674ba8230 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 20 Feb 2024 13:35:29 +0100 Subject: [PATCH 103/213] Update pro ref --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index 6f3a0b7f72..60e47a8249 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit 6f3a0b7f72d16f9604179af98ff7602ca0df2737 +Subproject commit 60e47a8249fd6291a6bc20fe3fe6776b11938fa1 From 91d45024e2b675668f2692185d8aba6ec376243c Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 20 Feb 2024 12:50:11 +0000 Subject: [PATCH 104/213] Bump version to 2.20.3 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 04f5c6e880..1cba488aa3 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.20.2", + "version": "2.20.3", "npmClient": "yarn", "packages": [ "packages/*", From 5dfa46037408b1fe7e8026a15e81d90d7234c8af Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 20 Feb 2024 16:23:35 +0000 Subject: [PATCH 105/213] Disabling VM by default in string-templates, backend services *MUST* set their JS runner specifically rather than assuming the VM library by default. --- .../src/helpers/javascript.js | 7 +++- packages/string-templates/src/index.js | 37 +++++++++++-------- packages/string-templates/src/utilities.js | 8 ++++ packages/string-templates/test/vm.spec.js | 27 ++++++++++++++ 4 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 packages/string-templates/test/vm.spec.js diff --git a/packages/string-templates/src/helpers/javascript.js b/packages/string-templates/src/helpers/javascript.js index 4a7f602690..7827736812 100644 --- a/packages/string-templates/src/helpers/javascript.js +++ b/packages/string-templates/src/helpers/javascript.js @@ -1,4 +1,4 @@ -const { atob } = require("../utilities") +const { atob, isBackendService, isJSAllowed } = require("../utilities") const cloneDeep = require("lodash.clonedeep") const { LITERAL_MARKER } = require("../helpers/constants") const { getJsHelperList } = require("./list") @@ -7,6 +7,9 @@ const { getJsHelperList } = require("./list") // This setter is used in the entrypoint (either index.js or index.mjs). let runJS module.exports.setJSRunner = runner => (runJS = runner) +module.exports.removeJSRunner = () => { + runJS = undefined +} let onErrorLog module.exports.setOnErrorLog = delegate => (onErrorLog = delegate) @@ -39,7 +42,7 @@ const getContextValue = (path, context) => { // Evaluates JS code against a certain context module.exports.processJS = (handlebars, context) => { - if (process && process.env.NO_JS) { + if (!isJSAllowed() || (isBackendService() && !runJS)) { throw new Error("JS disabled in environment.") } try { diff --git a/packages/string-templates/src/index.js b/packages/string-templates/src/index.js index bcd63d2e6f..2dc360bd96 100644 --- a/packages/string-templates/src/index.js +++ b/packages/string-templates/src/index.js @@ -2,7 +2,7 @@ const vm = require("vm") const handlebars = require("handlebars") const { registerAll, registerMinimum } = require("./helpers/index") const processors = require("./processors") -const { atob, btoa } = require("./utilities") +const { atob, btoa, isBackendService, isJSAllowed } = require("./utilities") const manifest = require("../manifest.json") const { FIND_HBS_REGEX, @@ -404,18 +404,25 @@ module.exports.JsErrorTimeout = errors.JsErrorTimeout module.exports.helpersToRemoveForJs = helpersToRemoveForJs -if (process && !process.env.NO_JS) { - /** - * Use polyfilled vm to run JS scripts in a browser Env - */ - javascript.setJSRunner((js, context) => { - context = { - ...context, - alert: undefined, - setInterval: undefined, - setTimeout: undefined, - } - vm.createContext(context) - return vm.runInNewContext(js, context, { timeout: 1000 }) - }) +function defaultJSSetup() { + if (!isBackendService()) { + /** + * Use polyfilled vm to run JS scripts in a browser Env + */ + javascript.setJSRunner((js, context) => { + context = { + ...context, + alert: undefined, + setInterval: undefined, + setTimeout: undefined, + } + vm.createContext(context) + return vm.runInNewContext(js, context, { timeout: 1000 }) + }) + } else { + javascript.removeJSRunner() + } } +defaultJSSetup() + +module.exports.defaultJSSetup = defaultJSSetup diff --git a/packages/string-templates/src/utilities.js b/packages/string-templates/src/utilities.js index 775c150e1b..00b2d7d855 100644 --- a/packages/string-templates/src/utilities.js +++ b/packages/string-templates/src/utilities.js @@ -4,6 +4,14 @@ module.exports.FIND_HBS_REGEX = /{{([^{].*?)}}/g module.exports.FIND_ANY_HBS_REGEX = /{?{{([^{].*?)}}}?/g module.exports.FIND_TRIPLE_HBS_REGEX = /{{{([^{].*?)}}}/g +module.exports.isBackendService = () => { + return typeof window === "undefined" +} + +module.exports.isJSAllowed = () => { + return process && !process.env.NO_JS +} + // originally this could be done with a single regex using look behinds // but safari does not support this feature // original regex: /(? { + const utilities = jest.requireActual("../src/utilities") + return { + ...utilities, + isBackendService: jest.fn().mockReturnValue(true), + } +}) +const { defaultJSSetup, processStringSync, encodeJSBinding } = require("../src") +const { isBackendService } = require("../src/utilities") +const mockedBackendService = jest.mocked(isBackendService) + +const binding = encodeJSBinding("return 1") +describe("confirm VM is available when expected and when not", () => { + it("shouldn't have JS available in a backend service by default", () => { + defaultJSSetup() + const result = processStringSync(binding, {}) + // shouldn't process at all + expect(result).toBe(binding) + }) + + it("should have JS available in frontend environments", () => { + mockedBackendService.mockReturnValue(false) + defaultJSSetup() + const result = processStringSync(binding, {}) + expect(result).toBe(1) + }) +}) From f294497b4a9e82cb1da47d99183e576cf6e03e16 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 20 Feb 2024 17:38:33 +0100 Subject: [PATCH 106/213] Update submodule ref --- packages/account-portal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/account-portal b/packages/account-portal index 8c446c4ba3..d643d74c57 160000 --- a/packages/account-portal +++ b/packages/account-portal @@ -1 +1 @@ -Subproject commit 8c446c4ba385592127fa31755d3b64467b291882 +Subproject commit d643d74c577a2ddb782489a6907639461cbcc438 From 4e61230c9a30be5f1c024c050fa8c12c4e01bf94 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 20 Feb 2024 17:17:13 +0000 Subject: [PATCH 107/213] Removing unused function. --- packages/string-templates/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/string-templates/src/index.js b/packages/string-templates/src/index.js index 2dc360bd96..0125b9e0ab 100644 --- a/packages/string-templates/src/index.js +++ b/packages/string-templates/src/index.js @@ -2,7 +2,7 @@ const vm = require("vm") const handlebars = require("handlebars") const { registerAll, registerMinimum } = require("./helpers/index") const processors = require("./processors") -const { atob, btoa, isBackendService, isJSAllowed } = require("./utilities") +const { atob, btoa, isBackendService } = require("./utilities") const manifest = require("../manifest.json") const { FIND_HBS_REGEX, From 41599540391cf8e5ef788ead457eb47088a4f23b Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Tue, 20 Feb 2024 14:23:42 -0300 Subject: [PATCH 108/213] acct portal submodule --- packages/account-portal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/account-portal b/packages/account-portal index d643d74c57..4384bc742c 160000 --- a/packages/account-portal +++ b/packages/account-portal @@ -1 +1 @@ -Subproject commit d643d74c577a2ddb782489a6907639461cbcc438 +Subproject commit 4384bc742ca22fb1e9bf91843e65ae929daf17e2 From 2145480572549d2fb1590e98e3da4521cf5649e4 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 20 Feb 2024 18:09:43 +0000 Subject: [PATCH 109/213] Bump version to 2.20.4 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 1cba488aa3..41b473161a 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.20.3", + "version": "2.20.4", "npmClient": "yarn", "packages": [ "packages/*", From dfb1774d2ce1044cd1c65e25e0f5ecd312d7bd0f Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Tue, 20 Feb 2024 16:32:55 -0300 Subject: [PATCH 110/213] bump default memory unit --- packages/server/src/environment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index 873c392942..7842a9b3dc 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -27,7 +27,7 @@ const DEFAULTS = { TEMPLATE_REPOSITORY: "app", PLUGINS_DIR: "/plugins", FORKED_PROCESS_NAME: "main", - JS_RUNNER_MEMORY_LIMIT: 64, + JS_RUNNER_MEMORY_LIMIT: 96, } const QUERY_THREAD_TIMEOUT = From 73fe2e0d1d9ff4e8a5fc5a8f2cf3fded3304c16c Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Tue, 20 Feb 2024 16:35:34 -0300 Subject: [PATCH 111/213] update JS per execution time --- packages/server/src/environment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index 7842a9b3dc..f304ce4eb2 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -23,11 +23,11 @@ const DEFAULTS = { AUTOMATION_THREAD_TIMEOUT: 12000, AUTOMATION_SYNC_TIMEOUT: 120000, AUTOMATION_MAX_ITERATIONS: 200, - JS_PER_EXECUTION_TIME_LIMIT_MS: 1000, + JS_PER_EXECUTION_TIME_LIMIT_MS: 1500, TEMPLATE_REPOSITORY: "app", PLUGINS_DIR: "/plugins", FORKED_PROCESS_NAME: "main", - JS_RUNNER_MEMORY_LIMIT: 96, + JS_RUNNER_MEMORY_LIMIT: 64, } const QUERY_THREAD_TIMEOUT = From 033ab7110906144117990606063823506247c92d Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 20 Feb 2024 19:51:22 +0000 Subject: [PATCH 112/213] Bump version to 2.20.5 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 41b473161a..a62c15997d 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.20.4", + "version": "2.20.5", "npmClient": "yarn", "packages": [ "packages/*", From e988890a7ee6ee9458218d913788101e2cf2b523 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 21 Feb 2024 10:12:06 +0100 Subject: [PATCH 113/213] Remove defaultUserValues from test config --- .../src/tests/utilities/TestConfiguration.ts | 81 ++++++++----------- 1 file changed, 33 insertions(+), 48 deletions(-) diff --git a/packages/server/src/tests/utilities/TestConfiguration.ts b/packages/server/src/tests/utilities/TestConfiguration.ts index ea3204536a..00550c2c24 100644 --- a/packages/server/src/tests/utilities/TestConfiguration.ts +++ b/packages/server/src/tests/utilities/TestConfiguration.ts @@ -76,14 +76,6 @@ mocks.licenses.useUnlimited() dbInit() -type DefaultUserValues = { - globalUserId: string - email: string - firstName: string - lastName: string - csrfToken: string -} - export interface TableToBuild extends Omit { sourceId?: string sourceType?: TableSourceType @@ -105,8 +97,8 @@ export default class TestConfiguration { automation: any datasource?: Datasource tenantId?: string - defaultUserValues: DefaultUserValues api: API + csrfToken?: string constructor(openServer = true) { if (openServer) { @@ -121,21 +113,10 @@ export default class TestConfiguration { } this.appId = null this.allApps = [] - this.defaultUserValues = this.populateDefaultUserValues() this.api = new API(this) } - populateDefaultUserValues(): DefaultUserValues { - return { - globalUserId: `us_${newid()}`, - email: generator.email(), - firstName: generator.first(), - lastName: generator.last(), - csrfToken: generator.hash(), - } - } - getRequest() { return this.request } @@ -160,15 +141,6 @@ export default class TestConfiguration { return this.prodAppId } - getUserDetails() { - return { - globalId: this.defaultUserValues.globalUserId, - email: this.defaultUserValues.email, - firstName: this.defaultUserValues.firstName, - lastName: this.defaultUserValues.lastName, - } - } - async doInContext( appId: string | null, task: () => Promise @@ -300,15 +272,27 @@ export default class TestConfiguration { } // USER / AUTH - async globalUser({ - id = this.defaultUserValues.globalUserId, - firstName = this.defaultUserValues.firstName, - lastName = this.defaultUserValues.lastName, - builder = true, - admin = false, - email = this.defaultUserValues.email, - roles, - }: any = {}): Promise { + async globalUser( + config: { + id?: string + firstName?: string + lastName?: string + builder?: boolean + admin?: boolean + email?: string + roles?: any + } = {} + ): Promise { + const { + id = `us_${newid()}`, + firstName = generator.first(), + lastName = generator.last(), + builder = true, + admin = false, + email, + roles, + } = config + const db = tenancy.getTenantDB(this.getTenantId()) let existing try { @@ -327,7 +311,7 @@ export default class TestConfiguration { await sessions.createASession(id, { sessionId: "sessionid", tenantId: this.getTenantId(), - csrfToken: this.defaultUserValues.csrfToken, + csrfToken: this.csrfToken, }) if (builder) { user.builder = { global: true } @@ -358,9 +342,9 @@ export default class TestConfiguration { } = {} ): Promise { let { id, firstName, lastName, email, builder, admin, roles } = user - firstName = firstName || this.defaultUserValues.firstName - lastName = lastName || this.defaultUserValues.lastName - email = email || this.defaultUserValues.email + ;(firstName = firstName || generator.first()), + (lastName = lastName || generator.last()), + (email = email || generator.email()) roles = roles || {} if (builder == null) { builder = true @@ -448,7 +432,7 @@ export default class TestConfiguration { defaultHeaders(extras = {}, prodApp = false) { const tenantId = this.getTenantId() const authObj: AuthToken = { - userId: this.defaultUserValues.globalUserId, + userId: this.user.globalUserId, sessionId: "sessionid", tenantId, } @@ -457,7 +441,7 @@ export default class TestConfiguration { const headers: any = { Accept: "application/json", Cookie: [`${constants.Cookie.Auth}=${authToken}`], - [constants.Header.CSRF_TOKEN]: this.defaultUserValues.csrfToken, + [constants.Header.CSRF_TOKEN]: this.csrfToken, Host: this.tenantHost(), ...extras, } @@ -487,7 +471,7 @@ export default class TestConfiguration { async basicRoleHeaders() { return await this.roleHeaders({ - email: this.defaultUserValues.email, + email: generator.email(), builder: false, prodApp: true, roleId: roles.BUILTIN_ROLE_IDS.BASIC, @@ -495,7 +479,7 @@ export default class TestConfiguration { } async roleHeaders({ - email = this.defaultUserValues.email, + email = generator.email(), roleId = roles.BUILTIN_ROLE_IDS.ADMIN, builder = false, prodApp = true, @@ -519,11 +503,12 @@ export default class TestConfiguration { } async newTenant(appName = newid()): Promise { - this.defaultUserValues = this.populateDefaultUserValues() this.tenantId = structures.tenant.id() this.user = await this.globalUser() this.globalUserId = this.user._id this.userMetadataId = generateUserMetadataID(this.globalUserId) + + this.csrfToken = generator.hash() return this.createApp(appName) } @@ -533,7 +518,7 @@ export default class TestConfiguration { // API - async generateApiKey(userId = this.defaultUserValues.globalUserId) { + async generateApiKey(userId = this.user.globalUserId) { const db = tenancy.getTenantDB(this.getTenantId()) const id = dbCore.generateDevInfoID(userId) let devInfo: any From f6e968efe848b568b8edeb59a17bf764e8a506a1 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 21 Feb 2024 10:18:46 +0100 Subject: [PATCH 114/213] Fix test --- packages/server/src/sdk/users/tests/utils.spec.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/server/src/sdk/users/tests/utils.spec.ts b/packages/server/src/sdk/users/tests/utils.spec.ts index 86dc411caf..efe790d49b 100644 --- a/packages/server/src/sdk/users/tests/utils.spec.ts +++ b/packages/server/src/sdk/users/tests/utils.spec.ts @@ -84,7 +84,8 @@ describe("syncGlobalUsers", () => { await syncGlobalUsers() const metadata = await rawUserMetadata() - expect(metadata).toHaveLength(2) + + expect(metadata).toHaveLength(2 + 1) // ADMIN user created in test bootstrap still in the application expect(metadata).toContainEqual( expect.objectContaining({ _id: db.generateUserMetadataID(user1._id!), @@ -121,7 +122,7 @@ describe("syncGlobalUsers", () => { await syncGlobalUsers() const metadata = await rawUserMetadata() - expect(metadata).toHaveLength(1) //ADMIN user created in test bootstrap still in the application + expect(metadata).toHaveLength(1) // ADMIN user created in test bootstrap still in the application }) }) }) From 0b5226413b7d76353685c1e70eb9eb18c1a7f922 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 21 Feb 2024 10:36:17 +0100 Subject: [PATCH 115/213] Fix ids --- .../src/tests/utilities/TestConfiguration.ts | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/server/src/tests/utilities/TestConfiguration.ts b/packages/server/src/tests/utilities/TestConfiguration.ts index 00550c2c24..0204eeb178 100644 --- a/packages/server/src/tests/utilities/TestConfiguration.ts +++ b/packages/server/src/tests/utilities/TestConfiguration.ts @@ -91,7 +91,6 @@ export default class TestConfiguration { prodApp: any prodAppId: any user: any - globalUserId: any userMetadataId: any table?: Table automation: any @@ -100,6 +99,10 @@ export default class TestConfiguration { api: API csrfToken?: string + private get globalUserId() { + return this.user._id + } + constructor(openServer = true) { if (openServer) { // use a random port because it doesn't matter @@ -141,6 +144,15 @@ export default class TestConfiguration { return this.prodAppId } + getUserDetails() { + return { + globalId: this.globalUserId, + email: this.user.email, + firstName: this.user.firstName, + lastName: this.user.lastName, + } + } + async doInContext( appId: string | null, task: () => Promise @@ -432,7 +444,7 @@ export default class TestConfiguration { defaultHeaders(extras = {}, prodApp = false) { const tenantId = this.getTenantId() const authObj: AuthToken = { - userId: this.user.globalUserId, + userId: this.globalUserId, sessionId: "sessionid", tenantId, } @@ -505,8 +517,7 @@ export default class TestConfiguration { async newTenant(appName = newid()): Promise { this.tenantId = structures.tenant.id() this.user = await this.globalUser() - this.globalUserId = this.user._id - this.userMetadataId = generateUserMetadataID(this.globalUserId) + this.userMetadataId = generateUserMetadataID(this.user._id) this.csrfToken = generator.hash() return this.createApp(appName) @@ -518,7 +529,7 @@ export default class TestConfiguration { // API - async generateApiKey(userId = this.user.globalUserId) { + async generateApiKey(userId = this.user._id) { const db = tenancy.getTenantDB(this.getTenantId()) const id = dbCore.generateDevInfoID(userId) let devInfo: any From f7d5ccee3c95a68f406d3e3ced363dfd53cd50fb Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 21 Feb 2024 10:42:36 +0100 Subject: [PATCH 116/213] Fix setting up email --- packages/server/src/tests/utilities/TestConfiguration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/tests/utilities/TestConfiguration.ts b/packages/server/src/tests/utilities/TestConfiguration.ts index 0204eeb178..5b20f83d77 100644 --- a/packages/server/src/tests/utilities/TestConfiguration.ts +++ b/packages/server/src/tests/utilities/TestConfiguration.ts @@ -301,7 +301,7 @@ export default class TestConfiguration { lastName = generator.last(), builder = true, admin = false, - email, + email = generator.email(), roles, } = config From f68e7359c6379096a55db163bb07bb4b6492853f Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 21 Feb 2024 10:57:49 +0100 Subject: [PATCH 117/213] Fix csrf usage --- packages/server/src/tests/utilities/TestConfiguration.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/server/src/tests/utilities/TestConfiguration.ts b/packages/server/src/tests/utilities/TestConfiguration.ts index 5b20f83d77..bbe3260d26 100644 --- a/packages/server/src/tests/utilities/TestConfiguration.ts +++ b/packages/server/src/tests/utilities/TestConfiguration.ts @@ -515,11 +515,12 @@ export default class TestConfiguration { } async newTenant(appName = newid()): Promise { + this.csrfToken = generator.hash() + this.tenantId = structures.tenant.id() this.user = await this.globalUser() this.userMetadataId = generateUserMetadataID(this.user._id) - this.csrfToken = generator.hash() return this.createApp(appName) } From 73bf29ab3c0edab5615f56d65c6410fcaf1cdc4d Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 21 Feb 2024 11:22:43 +0100 Subject: [PATCH 118/213] Clean code --- .../src/tests/utilities/TestConfiguration.ts | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/server/src/tests/utilities/TestConfiguration.ts b/packages/server/src/tests/utilities/TestConfiguration.ts index bbe3260d26..8e6ecdfeb1 100644 --- a/packages/server/src/tests/utilities/TestConfiguration.ts +++ b/packages/server/src/tests/utilities/TestConfiguration.ts @@ -353,14 +353,16 @@ export default class TestConfiguration { roles?: UserRoles } = {} ): Promise { - let { id, firstName, lastName, email, builder, admin, roles } = user - ;(firstName = firstName || generator.first()), - (lastName = lastName || generator.last()), - (email = email || generator.email()) - roles = roles || {} - if (builder == null) { - builder = true - } + const { + id, + firstName = generator.first(), + lastName = generator.last(), + email = generator.email(), + builder = true, + admin, + roles, + } = user + const globalId = !id ? `us_${Math.random()}` : `us_${id}` const resp = await this.globalUser({ id: globalId, @@ -369,7 +371,7 @@ export default class TestConfiguration { email, builder, admin, - roles, + roles: roles || {}, }) await cache.user.invalidateUser(globalId) return resp From f417c2d8a4d96cc958ecb3a35281030cfe6c1f2c Mon Sep 17 00:00:00 2001 From: Joe <49767913+joebudi@users.noreply.github.com> Date: Wed, 21 Feb 2024 13:28:35 +0000 Subject: [PATCH 119/213] Joe's lab day minor updates (#12944) * Change default button type to CTA - change default button type to CTA - change ordering of types/variants * Fix layout shift within portal Within the portal, when navigating from screen to screen, there's a slight layout shift caused by the scrollbar. This is a small fix. * row/column icons change The current row/column icons for positioning components are confusing. I believe these icons are easier to understand. * Fix for horizontal scrollbar showing When adding/removing actions within automations, the horizontal scrollbar flashes. Fix. * Title change for Upload data Upload data is not wrong, but it's best to be explicit. * Increase size of upgrade button * small fix for the styling inconsistency * Dianostics padding fix * lint fix * update account-portal * update icons --------- Co-authored-by: melohagan <101575380+melohagan@users.noreply.github.com> Co-authored-by: Mel O'Hagan --- packages/bbui/src/Layout/Page.svelte | 1 + packages/bbui/src/Typography/Body.svelte | 6 +++++ packages/bbui/src/Typography/Heading.svelte | 4 +++ .../FlowChart/FlowChart.svelte | 1 + .../builder/app/[application]/data/new.svelte | 2 +- .../portal/_components/UpgradeButton.svelte | 4 +-- .../portal/settings/diagnostics.svelte | 9 ++++--- packages/client/manifest.json | 26 +++++++++---------- .../client/src/components/app/Button.svelte | 2 +- 9 files changed, 35 insertions(+), 20 deletions(-) diff --git a/packages/bbui/src/Layout/Page.svelte b/packages/bbui/src/Layout/Page.svelte index 57c264231b..2169a12459 100644 --- a/packages/bbui/src/Layout/Page.svelte +++ b/packages/bbui/src/Layout/Page.svelte @@ -43,6 +43,7 @@ flex-direction: row; justify-content: flex-start; align-items: stretch; + overflow-y: scroll !important; flex: 1 1 auto; overflow-x: hidden; } diff --git a/packages/bbui/src/Typography/Body.svelte b/packages/bbui/src/Typography/Body.svelte index 71b4dca248..2123eeee95 100644 --- a/packages/bbui/src/Typography/Body.svelte +++ b/packages/bbui/src/Typography/Body.svelte @@ -20,3 +20,9 @@ >

    + + diff --git a/packages/bbui/src/Typography/Heading.svelte b/packages/bbui/src/Typography/Heading.svelte index c0d0571143..50522fffc3 100644 --- a/packages/bbui/src/Typography/Heading.svelte +++ b/packages/bbui/src/Typography/Heading.svelte @@ -21,4 +21,8 @@ h1 { font-family: var(--font-accent); } + + h1 { + text-wrap: balance; + } diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte index 4c458a5627..1ace6c0f00 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte @@ -130,6 +130,7 @@ flex-grow: 1; padding: 23px 23px 80px; box-sizing: border-box; + overflow-x: hidden; } .header.scrolling { diff --git a/packages/builder/src/pages/builder/app/[application]/data/new.svelte b/packages/builder/src/pages/builder/app/[application]/data/new.svelte index c07a9f563d..20efd3667b 100644 --- a/packages/builder/src/pages/builder/app/[application]/data/new.svelte +++ b/packages/builder/src/pages/builder/app/[application]/data/new.svelte @@ -77,7 +77,7 @@ internalTableModal.show({ promptUpload: true })} - title="Upload data" + title="Upload CSV / JSON" description="Non-relational" {disabled} > diff --git a/packages/builder/src/pages/builder/portal/_components/UpgradeButton.svelte b/packages/builder/src/pages/builder/portal/_components/UpgradeButton.svelte index b12efd6f03..59a791538a 100644 --- a/packages/builder/src/pages/builder/portal/_components/UpgradeButton.svelte +++ b/packages/builder/src/pages/builder/portal/_components/UpgradeButton.svelte @@ -10,7 +10,7 @@ {#if $admin.cloud && $auth?.user?.accountPortalAccess} + +
    + +
    (showTooltip = true)} diff --git a/packages/bbui/src/IconPicker/IconPicker.svelte b/packages/bbui/src/IconPicker/IconPicker.svelte index b3cc72daa3..3cd7a16eb0 100644 --- a/packages/bbui/src/IconPicker/IconPicker.svelte +++ b/packages/bbui/src/IconPicker/IconPicker.svelte @@ -58,6 +58,8 @@ } + +
    (open = true)}>
    + +
    + +
    copyToClipboard(value)}> diff --git a/packages/bbui/src/List/ListItem.svelte b/packages/bbui/src/List/ListItem.svelte index 28015c4c57..76b242cf9c 100644 --- a/packages/bbui/src/List/ListItem.svelte +++ b/packages/bbui/src/List/ListItem.svelte @@ -15,6 +15,8 @@ $: initials = avatar ? title?.[0] : null + +
    {#if icon} diff --git a/packages/bbui/src/Menu/Item.svelte b/packages/bbui/src/Menu/Item.svelte index ed759f5b10..05a33adda9 100644 --- a/packages/bbui/src/Menu/Item.svelte +++ b/packages/bbui/src/Menu/Item.svelte @@ -33,6 +33,7 @@ } +
  • + +
    Click me {remaining} diff --git a/packages/bbui/src/Modal/Modal.svelte b/packages/bbui/src/Modal/Modal.svelte index da97bf332e..f891d0584d 100644 --- a/packages/bbui/src/Modal/Modal.svelte +++ b/packages/bbui/src/Modal/Modal.svelte @@ -100,6 +100,7 @@ --> {#if visible} +
    + +
    + +