From 3f336ecce586385174f57f91ecd0ea1e44ffde73 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Thu, 10 Jul 2025 11:55:13 -0400 Subject: [PATCH 01/26] feat(save-user-data): create a user data abstract class --- packages/atlas-service/src/secret-store.ts | 6 +- .../src/components/diagram-card.spec.tsx | 2 +- .../services/data-model-storage-electron.tsx | 8 ++- .../src/preferences-persistent-storage.ts | 6 +- .../src/user-storage.ts | 6 +- .../src/modules/history-storage.ts | 4 +- packages/compass-user-data/src/index.ts | 2 +- .../compass-user-data/src/user-data.spec.ts | 6 +- packages/compass-user-data/src/user-data.ts | 62 ++++++++++++++++--- .../src/compass-main-connection-storage.ts | 6 +- .../src/compass-pipeline-storage.ts | 6 +- .../src/compass-query-storage.ts | 52 ++++++---------- 12 files changed, 99 insertions(+), 67 deletions(-) diff --git a/packages/atlas-service/src/secret-store.ts b/packages/atlas-service/src/secret-store.ts index 29118af3975..a303151250f 100644 --- a/packages/atlas-service/src/secret-store.ts +++ b/packages/atlas-service/src/secret-store.ts @@ -1,13 +1,13 @@ -import { UserData, z } from '@mongodb-js/compass-user-data'; +import { FileUserData, z } from '@mongodb-js/compass-user-data'; import { safeStorage } from 'electron'; const AtlasPluginStateSchema = z.string().optional(); export class SecretStore { - private readonly userData: UserData; + private readonly userData: FileUserData; private readonly fileName = 'AtlasPluginState'; constructor(basePath?: string) { - this.userData = new UserData(AtlasPluginStateSchema, { + this.userData = new FileUserData(AtlasPluginStateSchema, { subdir: 'AtlasState', basePath, }); diff --git a/packages/compass-data-modeling/src/components/diagram-card.spec.tsx b/packages/compass-data-modeling/src/components/diagram-card.spec.tsx index 3f97c7e97a0..6623cc0d526 100644 --- a/packages/compass-data-modeling/src/components/diagram-card.spec.tsx +++ b/packages/compass-data-modeling/src/components/diagram-card.spec.tsx @@ -42,6 +42,6 @@ describe('DiagramCard', () => { render(); expect(screen.getByText('Test Diagram')).to.be.visible; expect(screen.getByText('someDatabase')).to.be.visible; - expect(screen.getByText('Last modified: October 3, 2023')).to.be.visible; + expect(screen.getByText(/modified/)).to.be.visible; }); }); diff --git a/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx b/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx index 29c23458f3e..fa7a62f77e9 100644 --- a/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx +++ b/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { UserData } from '@mongodb-js/compass-user-data'; +import { FileUserData } from '@mongodb-js/compass-user-data'; import type { DataModelStorage, MongoDBDataModelDescription, @@ -8,9 +8,11 @@ import { MongoDBDataModelDescriptionSchema } from './data-model-storage'; import { DataModelStorageServiceProvider } from '../provider'; class DataModelStorageElectron implements DataModelStorage { - private readonly userData: UserData; + private readonly userData: FileUserData< + typeof MongoDBDataModelDescriptionSchema + >; constructor(basePath?: string) { - this.userData = new UserData(MongoDBDataModelDescriptionSchema, { + this.userData = new FileUserData(MongoDBDataModelDescriptionSchema, { subdir: 'DataModelDescriptions', basePath, }); diff --git a/packages/compass-preferences-model/src/preferences-persistent-storage.ts b/packages/compass-preferences-model/src/preferences-persistent-storage.ts index 4507f7ccacf..2a66dee37d5 100644 --- a/packages/compass-preferences-model/src/preferences-persistent-storage.ts +++ b/packages/compass-preferences-model/src/preferences-persistent-storage.ts @@ -1,4 +1,4 @@ -import { type z, UserData } from '@mongodb-js/compass-user-data'; +import { type z, FileUserData } from '@mongodb-js/compass-user-data'; import { getDefaultsForStoredPreferences, getPreferencesValidator, @@ -20,12 +20,12 @@ export type PreferencesSafeStorage = { export class PersistentStorage implements PreferencesStorage { private readonly file = 'General'; private readonly defaultPreferences = getDefaultsForStoredPreferences(); - private readonly userData: UserData; + private readonly userData: FileUserData; private preferences: StoredPreferences = getDefaultsForStoredPreferences(); private safeStorage?: PreferencesSafeStorage; constructor(basePath?: string, safeStorage?: PreferencesSafeStorage) { - this.userData = new UserData(getPreferencesValidator(), { + this.userData = new FileUserData(getPreferencesValidator(), { subdir: 'AppPreferences', basePath, }); diff --git a/packages/compass-preferences-model/src/user-storage.ts b/packages/compass-preferences-model/src/user-storage.ts index 044d6b04b30..fbaed7f7b27 100644 --- a/packages/compass-preferences-model/src/user-storage.ts +++ b/packages/compass-preferences-model/src/user-storage.ts @@ -1,6 +1,6 @@ import { z } from '@mongodb-js/compass-user-data'; import { UUID } from 'bson'; -import { UserData } from '@mongodb-js/compass-user-data'; +import { FileUserData } from '@mongodb-js/compass-user-data'; const UserSchema = z.object({ id: z.string().uuid(), @@ -24,9 +24,9 @@ export interface UserStorage { } export class UserStorageImpl implements UserStorage { - private readonly userData: UserData; + private readonly userData: FileUserData; constructor(basePath?: string) { - this.userData = new UserData(UserSchema, { + this.userData = new FileUserData(UserSchema, { subdir: 'Users', basePath, }); diff --git a/packages/compass-shell/src/modules/history-storage.ts b/packages/compass-shell/src/modules/history-storage.ts index f302a2cf892..5f1cab73a04 100644 --- a/packages/compass-shell/src/modules/history-storage.ts +++ b/packages/compass-shell/src/modules/history-storage.ts @@ -1,12 +1,12 @@ import { getAppName } from '@mongodb-js/compass-utils'; -import { UserData, z } from '@mongodb-js/compass-user-data'; +import { FileUserData, z } from '@mongodb-js/compass-user-data'; export class HistoryStorage { fileName = 'shell-history'; userData; constructor(basePath?: string) { - this.userData = new UserData(z.string().array(), { + this.userData = new FileUserData(z.string().array(), { // Todo: https://jira.mongodb.org/browse/COMPASS-7080 subdir: getAppName() ?? '', basePath, diff --git a/packages/compass-user-data/src/index.ts b/packages/compass-user-data/src/index.ts index f5b3b57d6bc..b216fd77f99 100644 --- a/packages/compass-user-data/src/index.ts +++ b/packages/compass-user-data/src/index.ts @@ -1,3 +1,3 @@ export type { Stats, ReadAllResult, ReadAllWithStatsResult } from './user-data'; -export { UserData } from './user-data'; +export { IUserData, FileUserData } from './user-data'; export { z } from 'zod'; diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index e1f2ead78cb..155a020092a 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -3,7 +3,7 @@ import { Stats } from 'fs'; import os from 'os'; import path from 'path'; import { expect } from 'chai'; -import { UserData, type UserDataOptions } from './user-data'; +import { FileUserData, type FileUserDataOptions } from './user-data'; import { z, type ZodError } from 'zod'; type ValidatorOptions = { @@ -44,11 +44,11 @@ describe('user-data', function () { const getUserData = ( userDataOpts: Partial< - UserDataOptions>> + FileUserDataOptions>> > = {}, validatorOpts: ValidatorOptions = {} ) => { - return new UserData(getTestSchema(validatorOpts), { + return new FileUserData(getTestSchema(validatorOpts), { subdir, basePath: tmpDir, ...userDataOpts, diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 92d3cd36d5e..7539686c51a 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -12,7 +12,7 @@ type SerializeContent = (content: I) => string; type DeserializeContent = (content: string) => unknown; type GetFileName = (id: string) => string; -export type UserDataOptions = { +export type FileUserDataOptions = { subdir: string; basePath?: string; serialize?: SerializeContent; @@ -20,6 +20,11 @@ export type UserDataOptions = { getFileName?: GetFileName; }; +export type AtlasUserDataOptions = { + serialize?: SerializeContent; + deserialize?: DeserializeContent; +}; + type ReadOptions = { ignoreErrors: boolean; }; @@ -63,28 +68,54 @@ export interface ReadAllWithStatsResult { errors: Error[]; } -export class UserData { +export abstract class IUserData { + protected readonly validator: T; + protected readonly serialize: SerializeContent>; + protected readonly deserialize: DeserializeContent; + protected static readonly semaphore = new Semaphore(100); + + constructor( + validator: T, + { + serialize = (content: z.input) => JSON.stringify(content, null, 2), + deserialize = JSON.parse, + }: { + serialize?: SerializeContent>; + deserialize?: DeserializeContent; + } = {} + ) { + this.validator = validator; + this.serialize = serialize; + this.deserialize = deserialize; + } + + abstract write(id: string, content: z.input): Promise; + abstract delete(id: string): Promise; + abstract readAll(options?: ReadOptions): Promise>; + abstract updateAttributes( + id: string, + data: Partial> + ): Promise>; +} + +export class FileUserData extends IUserData { private readonly subdir: string; private readonly basePath?: string; - private readonly serialize: SerializeContent>; - private readonly deserialize: DeserializeContent; private readonly getFileName: GetFileName; - private readonly semaphore = new Semaphore(100); constructor( - private readonly validator: T, + validator: T, { subdir, basePath, serialize = (content: z.input) => JSON.stringify(content, null, 2), deserialize = JSON.parse, getFileName = (id) => `${id}.json`, - }: UserDataOptions> + }: FileUserDataOptions> ) { + super(validator, { serialize, deserialize }); this.subdir = subdir; this.basePath = basePath; - this.deserialize = deserialize; - this.serialize = serialize; this.getFileName = getFileName; } @@ -126,7 +157,7 @@ export class UserData { let handle: fs.FileHandle | undefined = undefined; let release: (() => void) | undefined = undefined; try { - release = await this.semaphore.waitForRelease(); + release = await IUserData.semaphore.waitForRelease(); handle = await fs.open(absolutePath, 'r'); [stats, data] = await Promise.all([ handle.stat(), @@ -290,4 +321,15 @@ export class UserData { ) { return (await this.readOneWithStats(id, options))?.[0]; } + + async updateAttributes( + id: string, + data: Partial> + ): Promise> { + await this.write(id, { + ...((await this.readOne(id)) ?? {}), + ...data, + }); + return await this.readOne(id); + } } diff --git a/packages/connection-storage/src/compass-main-connection-storage.ts b/packages/connection-storage/src/compass-main-connection-storage.ts index ade7c9e9e6e..78f5380b735 100644 --- a/packages/connection-storage/src/compass-main-connection-storage.ts +++ b/packages/connection-storage/src/compass-main-connection-storage.ts @@ -24,7 +24,7 @@ import type { ImportConnectionOptions, ExportConnectionOptions, } from './import-export-connection'; -import { UserData, z } from '@mongodb-js/compass-user-data'; +import { FileUserData, z } from '@mongodb-js/compass-user-data'; import type { ConnectionStorage, AutoConnectPreferences, @@ -86,7 +86,7 @@ const ConnectionSchema: z.Schema = z .passthrough(); class CompassMainConnectionStorage implements ConnectionStorage { - private readonly userData: UserData; + private readonly userData: FileUserData; private readonly version = 1; private readonly maxAllowedRecentConnections = 10; @@ -95,7 +95,7 @@ class CompassMainConnectionStorage implements ConnectionStorage { private readonly ipcMain: ConnectionStorageIPCMain, basePath?: string ) { - this.userData = new UserData(ConnectionSchema, { + this.userData = new FileUserData(ConnectionSchema, { subdir: 'Connections', basePath, }); diff --git a/packages/my-queries-storage/src/compass-pipeline-storage.ts b/packages/my-queries-storage/src/compass-pipeline-storage.ts index daa5ae362eb..766fc0166a0 100644 --- a/packages/my-queries-storage/src/compass-pipeline-storage.ts +++ b/packages/my-queries-storage/src/compass-pipeline-storage.ts @@ -1,13 +1,13 @@ import type { Stats } from '@mongodb-js/compass-user-data'; -import { UserData } from '@mongodb-js/compass-user-data'; +import { FileUserData } from '@mongodb-js/compass-user-data'; import { PipelineSchema } from './pipeline-storage-schema'; import type { SavedPipeline } from './pipeline-storage-schema'; import type { PipelineStorage } from './pipeline-storage'; export class CompassPipelineStorage implements PipelineStorage { - private readonly userData: UserData; + private readonly userData: FileUserData; constructor(basePath?: string) { - this.userData = new UserData(PipelineSchema, { + this.userData = new FileUserData(PipelineSchema, { subdir: 'SavedPipelines', basePath, }); diff --git a/packages/my-queries-storage/src/compass-query-storage.ts b/packages/my-queries-storage/src/compass-query-storage.ts index e9b6b3b6169..2b1690d77ac 100644 --- a/packages/my-queries-storage/src/compass-query-storage.ts +++ b/packages/my-queries-storage/src/compass-query-storage.ts @@ -1,44 +1,30 @@ import { UUID, EJSON } from 'bson'; -import { UserData, type z } from '@mongodb-js/compass-user-data'; -import { - RecentQuerySchema, - FavoriteQuerySchema, - type RecentQuery, - type FavoriteQuery, -} from './query-storage-schema'; +import { type z } from '@mongodb-js/compass-user-data'; +import { type IUserData, FileUserData } from '@mongodb-js/compass-user-data'; +import { RecentQuerySchema, FavoriteQuerySchema } from './query-storage-schema'; import type { FavoriteQueryStorage, RecentQueryStorage } from './query-storage'; export type QueryStorageOptions = { basepath?: string; }; -export interface QueryStorageBackend { - loadAll(namespace?: string): Promise; - updateAttributes(id: string, data: Partial): Promise; - delete(id: string): Promise; - saveQuery(data: Omit): Promise; -} - -export abstract class CompassQueryStorage< - TSchema extends z.Schema, - TData extends z.output = z.output -> implements QueryStorageBackend -{ - protected readonly userData: UserData; +export abstract class CompassQueryStorage { + protected readonly userData: IUserData; constructor( schemaValidator: TSchema, protected readonly folder: string, protected readonly options: QueryStorageOptions ) { - this.userData = new UserData(schemaValidator, { + // TODO: logic for whether we're in compass web or compass desktop + this.userData = new FileUserData(schemaValidator, { subdir: folder, basePath: options.basepath, serialize: (content) => EJSON.stringify(content, undefined, 2), - deserialize: (content) => EJSON.parse(content), + deserialize: (content: string) => EJSON.parse(content), }); } - async loadAll(namespace?: string): Promise { + async loadAll(namespace?: string): Promise[]> { try { const { data } = await this.userData.readAll(); const sortedData = data @@ -52,23 +38,23 @@ export abstract class CompassQueryStorage< } } - async updateAttributes(id: string, data: Partial): Promise { - await this.userData.write(id, { - ...((await this.userData.readOne(id)) ?? {}), - ...data, - }); - return await this.userData.readOne(id); + async write(id: string, content: z.input): Promise { + return await this.userData.write(id, content); } async delete(id: string) { return await this.userData.delete(id); } - abstract saveQuery(data: any): Promise; + async updateAttributes(id: string, data: Partial>) { + return await this.userData.updateAttributes(id, data); + } + + abstract saveQuery(data: Partial>): Promise; } export class CompassRecentQueryStorage - extends CompassQueryStorage + extends CompassQueryStorage implements RecentQueryStorage { private readonly maxAllowedQueries = 30; @@ -88,6 +74,7 @@ export class CompassRecentQueryStorage } const _id = new UUID().toString(); + // this creates a recent query that we will write to system/db const recentQuery = { ...data, _id, @@ -98,7 +85,7 @@ export class CompassRecentQueryStorage } export class CompassFavoriteQueryStorage - extends CompassQueryStorage + extends CompassQueryStorage implements FavoriteQueryStorage { constructor(options: QueryStorageOptions = {}) { @@ -112,6 +99,7 @@ export class CompassFavoriteQueryStorage > ): Promise { const _id = new UUID().toString(); + // this creates a favorite query that we will write to system/db const favoriteQuery = { ...data, _id, From 78026a3f1064ccbf61c25de49b8e4cad44fe351f Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Thu, 10 Jul 2025 14:19:13 -0400 Subject: [PATCH 02/26] fix: rm defaults and add semaphore to FileUserData --- .../src/components/diagram-card.spec.tsx | 2 +- packages/compass-user-data/src/user-data.ts | 8 ++++---- packages/my-queries-storage/src/compass-query-storage.ts | 5 ++++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/compass-data-modeling/src/components/diagram-card.spec.tsx b/packages/compass-data-modeling/src/components/diagram-card.spec.tsx index 6623cc0d526..3f97c7e97a0 100644 --- a/packages/compass-data-modeling/src/components/diagram-card.spec.tsx +++ b/packages/compass-data-modeling/src/components/diagram-card.spec.tsx @@ -42,6 +42,6 @@ describe('DiagramCard', () => { render(); expect(screen.getByText('Test Diagram')).to.be.visible; expect(screen.getByText('someDatabase')).to.be.visible; - expect(screen.getByText(/modified/)).to.be.visible; + expect(screen.getByText('Last modified: October 3, 2023')).to.be.visible; }); }); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 7539686c51a..ec4cad6868f 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -72,7 +72,6 @@ export abstract class IUserData { protected readonly validator: T; protected readonly serialize: SerializeContent>; protected readonly deserialize: DeserializeContent; - protected static readonly semaphore = new Semaphore(100); constructor( validator: T, @@ -102,14 +101,15 @@ export class FileUserData extends IUserData { private readonly subdir: string; private readonly basePath?: string; private readonly getFileName: GetFileName; + protected readonly semaphore = new Semaphore(100); constructor( validator: T, { subdir, basePath, - serialize = (content: z.input) => JSON.stringify(content, null, 2), - deserialize = JSON.parse, + serialize, + deserialize, getFileName = (id) => `${id}.json`, }: FileUserDataOptions> ) { @@ -157,7 +157,7 @@ export class FileUserData extends IUserData { let handle: fs.FileHandle | undefined = undefined; let release: (() => void) | undefined = undefined; try { - release = await IUserData.semaphore.waitForRelease(); + release = await this.semaphore.waitForRelease(); handle = await fs.open(absolutePath, 'r'); [stats, data] = await Promise.all([ handle.stat(), diff --git a/packages/my-queries-storage/src/compass-query-storage.ts b/packages/my-queries-storage/src/compass-query-storage.ts index 2b1690d77ac..c133ee81c53 100644 --- a/packages/my-queries-storage/src/compass-query-storage.ts +++ b/packages/my-queries-storage/src/compass-query-storage.ts @@ -46,7 +46,10 @@ export abstract class CompassQueryStorage { return await this.userData.delete(id); } - async updateAttributes(id: string, data: Partial>) { + async updateAttributes( + id: string, + data: Partial> + ): Promise> { return await this.userData.updateAttributes(id, data); } From dc38640ff5b2706f2b6ed82f56c5169ea02b3af4 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Tue, 15 Jul 2025 14:53:09 -0400 Subject: [PATCH 03/26] feat(save-user-data): push for help --- packages/atlas-service/package.json | 2 + packages/compass-global-writes/src/index.ts | 1 + packages/compass-user-data/package.json | 3 + packages/compass-user-data/src/index.ts | 2 +- .../compass-user-data/src/user-data.spec.ts | 109 +++++++++++++ packages/compass-user-data/src/user-data.ts | 144 ++++++++++++++++++ packages/compass-user-data/tsconfig.json | 3 +- 7 files changed, 262 insertions(+), 2 deletions(-) diff --git a/packages/atlas-service/package.json b/packages/atlas-service/package.json index 09cfdb5a504..b3d84b58b50 100644 --- a/packages/atlas-service/package.json +++ b/packages/atlas-service/package.json @@ -28,11 +28,13 @@ ], "license": "SSPL", "exports": { + "./atlas-service": "./dist/atlas-service.js", "./main": "./main.js", "./renderer": "./renderer.js", "./provider": "./dist/provider.js" }, "compass:exports": { + "./atlas-service": "./src/atlas-service.ts", "./main": "./src/main.ts", "./renderer": "./src/renderer.ts", "./provider": "./src/provider.tsx" diff --git a/packages/compass-global-writes/src/index.ts b/packages/compass-global-writes/src/index.ts index 2a02dadad29..d908439c4b3 100644 --- a/packages/compass-global-writes/src/index.ts +++ b/packages/compass-global-writes/src/index.ts @@ -8,6 +8,7 @@ import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; import { atlasServiceLocator } from '@mongodb-js/atlas-service/provider'; +export { AtlasGlobalWritesService } from './services/atlas-global-writes-service'; const CompassGlobalWritesPluginProvider = registerCompassPlugin( { diff --git a/packages/compass-user-data/package.json b/packages/compass-user-data/package.json index 3d6d4633ac8..a1ee4b67d6d 100644 --- a/packages/compass-user-data/package.json +++ b/packages/compass-user-data/package.json @@ -51,6 +51,9 @@ "dependencies": { "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", + "@mongodb-js/atlas-service": "^0.49.0", + "@mongodb-js/compass-connections": "^0.31.0", + "compass-preferences-model": "^2.44.0", "write-file-atomic": "^5.0.1", "zod": "^3.25.17" }, diff --git a/packages/compass-user-data/src/index.ts b/packages/compass-user-data/src/index.ts index b216fd77f99..777475986fa 100644 --- a/packages/compass-user-data/src/index.ts +++ b/packages/compass-user-data/src/index.ts @@ -1,3 +1,3 @@ export type { Stats, ReadAllResult, ReadAllWithStatsResult } from './user-data'; -export { IUserData, FileUserData } from './user-data'; +export { IUserData, FileUserData, AtlasUserData } from './user-data'; export { z } from 'zod'; diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index 155a020092a..df6bbe4ee08 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -418,3 +418,112 @@ describe('user-data', function () { }); }); }); + +describe('AtlasUserData', function () { + let AtlasUserData: any; + let atlasServiceMock: any; + let validator: any; + let instance: any; + + before(async function () { + // Dynamically import AtlasUserData to avoid circular deps + const module = await import('./user-data'); + AtlasUserData = module.AtlasUserData; + validator = getTestSchema(); + }); + + beforeEach(function () { + atlasServiceMock = { + authenticatedFetch: sinon.stub(), + }; + instance = new AtlasUserData(validator, atlasServiceMock, { + groupId: 'test-group', + projectId: 'test-project', + endpoint: '/api/user-data', + }); + }); + + it('constructs with dependencies', function () { + expect(instance).to.have.property('atlasService', atlasServiceMock); + expect(instance).to.have.property('groupId', 'test-group'); + expect(instance).to.have.property('projectId', 'test-project'); + expect(instance).to.have.property('endpoint', '/api/user-data'); + }); + + it('write: calls authenticatedFetch and validates response', async function () { + const item = { name: 'Atlas', hasDarkMode: false }; + atlasServiceMock.authenticatedFetch.resolves({ + ok: true, + json: async () => await Promise.resolve(item), + }); + const result = await instance.write('id1', item); + expect(result).to.be.true; + expect(atlasServiceMock.authenticatedFetch.calledOnce).to.be.true; + }); + + it('write: handles API error', async function () { + atlasServiceMock.authenticatedFetch.resolves({ ok: false, status: 500 }); + const result = await instance.write('id1', { name: 'Atlas' }); + expect(result).to.be.false; + }); + + it('delete: calls authenticatedFetch and returns true on success', async function () { + atlasServiceMock.authenticatedFetch.resolves({ ok: true }); + const result = await instance.delete('id1'); + expect(result).to.be.true; + }); + + it('delete: returns false on API failure', async function () { + atlasServiceMock.authenticatedFetch.resolves({ ok: false }); + const result = await instance.delete('id1'); + expect(result).to.be.false; + }); + + it('readAll: returns validated items from API', async function () { + const items = [ + { name: 'Atlas', hasDarkMode: true }, + { name: 'Compass', hasDarkMode: false }, + ]; + atlasServiceMock.authenticatedFetch.resolves({ + ok: true, + json: async () => await Promise.resolve(items), + }); + const result = await instance.readAll(); + expect(result.data).to.have.lengthOf(2); + expect(result.errors).to.have.lengthOf(0); + expect(result.data[0]).to.have.property('name'); + }); + + it('readAll: returns errors for invalid items', async function () { + const items = [ + { name: 'Atlas', hasDarkMode: 'not-a-bool' }, + { name: 'Compass', hasDarkMode: false }, + ]; + atlasServiceMock.authenticatedFetch.resolves({ + ok: true, + json: async () => await Promise.resolve(items), + }); + const result = await instance.readAll(); + expect(result.data).to.have.lengthOf(1); + expect(result.errors).to.have.lengthOf(1); + }); + + it('updateAttributes: calls authenticatedFetch and validates response', async function () { + const attrs = { hasDarkMode: false }; + atlasServiceMock.authenticatedFetch.resolves({ + ok: true, + json: async () => + await Promise.resolve({ name: 'Atlas', hasDarkMode: false }), + }); + const result = await instance.updateAttributes('id1', attrs); + expect(result).to.deep.equal({ name: 'Atlas', hasDarkMode: false }); + }); + + it('updateAttributes: returns undefined on API error', async function () { + atlasServiceMock.authenticatedFetch.resolves({ ok: false }); + const result = await instance.updateAttributes('id1', { + hasDarkMode: true, + }); + expect(result).to.be.undefined; + }); +}); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index ec4cad6868f..ed89d5e75cf 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -5,6 +5,10 @@ import { getStoragePath } from '@mongodb-js/compass-utils'; import type { z } from 'zod'; import writeFile from 'write-file-atomic'; import { Semaphore } from './semaphore'; +import { AtlasService } from '@mongodb-js/atlas-service/atlas-service'; +import { atlasAuthServiceLocator } from '@mongodb-js/atlas-service/provider'; +import { preferencesLocator } from 'compass-preferences-model/provider'; +import { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; const { log, mongoLogId } = createLogger('COMPASS-USER-STORAGE'); @@ -333,3 +337,143 @@ export class FileUserData extends IUserData { return await this.readOne(id); } } + +// TODO: update endpoints to reflect the merged api endpoints +export class AtlasUserData extends IUserData { + private atlasService: AtlasService; + private readonly preferences = preferencesLocator(); + // private readonly preferences = null; + private readonly connectionInfoRef = connectionInfoRefLocator(); + // private readonly connectionInfoRef = null; + private readonly logger = createLogger('ATLAS-USER-STORAGE'); + private readonly groupId = + this.connectionInfoRef?.current?.atlasMetadata?.projectId; + private readonly orgId = + this.connectionInfoRef?.current?.atlasMetadata?.orgId; + // should this BASE_URL be a parameter passed to the constructor? + // this might make future usage of this code easier, if we want to call a different endpoint + private readonly BASE_URL = 'cluster-connection.cloud-local.mongodb.com'; + constructor( + validator: T, + { serialize, deserialize }: AtlasUserDataOptions> + ) { + super(validator, { serialize, deserialize }); + const authService = atlasAuthServiceLocator(); + // const authService = null; + const options = {}; + + this.atlasService = new AtlasService( + authService, + this.preferences, + this.logger, + options + ); + this.atlasService = null; + } + + async write(id: string, content: z.input): Promise { + this.validator.parse(content); + + // do not need to use id because content already contains the id + const response = await this.atlasService.authenticatedFetch(this.getUrl(), { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + id: id, + data: this.serialize(content), + createdAt: new Date(), + groupId: this.groupId, + }), + }); + // TODO: fix this error handling, should fit current compass needs + if (!response.ok) { + throw new Error( + `Failed to post data: ${response.status} ${response.statusText}` + ); + } + return true; + } + + async delete(id: string): Promise { + const response = await this.atlasService.authenticatedFetch( + this.getUrl() + `/${id}`, + { + method: 'DELETE', + } + ); + if (!response.ok) { + throw new Error( + `Failed to delete data: ${response.status} ${response.statusText}` + ); + } + return true; + } + + async readAll(): Promise> { + try { + const response = await this.atlasService.authenticatedFetch( + this.getUrl(), + { + method: 'GET', + headers: { + accept: 'application/json', + }, + } + ); + // TODO: fix this error handling, should fit current compass needs + if (!response.ok) { + throw new Error( + `Failed to get data: ${response.status} ${response.statusText}` + ); + } + const json = await response.json(); + const data = Array.isArray(json) + ? json.map((item) => + this.validator.parse(this.deserialize(item.data as string)) + ) + : []; + return { data, errors: [] }; + } catch (error) { + return { data: [], errors: [error as Error] }; + } + } + + async updateAttributes( + id: string, + data: Partial> + ): Promise> { + const response = await this.atlasService.authenticatedFetch( + this.getUrl() + `/${id}`, + { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + // TODO: not sure whether currently compass sometimes adds to data or always replaces it + // figure out if we should get all data, find specific query by id, then update using JS + body: this.serialize(data), + } + ); + if (!response.ok) { + throw new Error( + `Failed to update data: ${response.status} ${response.statusText}` + ); + } + const json = await response.json(); + // TODO: fix this, currently endpoint does not return the updated data + // so we need to decide whether this is necessary + return this.validator.parse(json.data); + } + + private getUrl() { + // if (endpoint.startsWith('/')) { + // endpoint = endpoint.slice(1); + // } + // if (endpoint.endsWith('/')) { + // endpoint = endpoint.slice(0, -1); + // } + return `${this.BASE_URL}/queries/favorites/${this.orgId}/${this.groupId}`; + } +} diff --git a/packages/compass-user-data/tsconfig.json b/packages/compass-user-data/tsconfig.json index ecd0a14474a..75250566a5d 100644 --- a/packages/compass-user-data/tsconfig.json +++ b/packages/compass-user-data/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "@mongodb-js/tsconfig-compass/tsconfig.common.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + "skipLibCheck": true }, "include": ["src/**/*"], "exclude": ["./src/**/*.spec.*"] From 41abc962c8b41b9ab7d4470767fb7b7653c33f21 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Tue, 15 Jul 2025 15:41:58 -0400 Subject: [PATCH 04/26] feat(save-user-data): comment out nulls --- package-lock.json | 6 ++++++ packages/compass-user-data/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index c5a09a2724a..0841986555c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47429,8 +47429,11 @@ "version": "0.7.5", "license": "SSPL", "dependencies": { + "@mongodb-js/atlas-service": "^0.49.0", + "@mongodb-js/compass-connections": "^1.64.0", "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", + "compass-preferences-model": "^2.44.0", "write-file-atomic": "^5.0.1", "zod": "^3.25.17" }, @@ -59073,6 +59076,8 @@ "@mongodb-js/compass-user-data": { "version": "file:packages/compass-user-data", "requires": { + "@mongodb-js/atlas-service": "^0.49.0", + "@mongodb-js/compass-connections": "^1.64.0", "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", "@mongodb-js/eslint-config-compass": "^1.4.1", @@ -59084,6 +59089,7 @@ "@types/sinon-chai": "^3.2.5", "@types/write-file-atomic": "^4.0.1", "chai": "^4.3.6", + "compass-preferences-model": "^2.44.0", "depcheck": "^1.4.1", "gen-esm-wrapper": "^1.1.0", "mocha": "^10.2.0", diff --git a/packages/compass-user-data/package.json b/packages/compass-user-data/package.json index a1ee4b67d6d..9c17a8279c0 100644 --- a/packages/compass-user-data/package.json +++ b/packages/compass-user-data/package.json @@ -52,7 +52,7 @@ "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", "@mongodb-js/atlas-service": "^0.49.0", - "@mongodb-js/compass-connections": "^0.31.0", + "@mongodb-js/compass-connections": "^1.64.0", "compass-preferences-model": "^2.44.0", "write-file-atomic": "^5.0.1", "zod": "^3.25.17" From e90412eac1dc2198ba4248e4913adaf9cdc18e70 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Thu, 10 Jul 2025 11:55:13 -0400 Subject: [PATCH 05/26] feat(save-user-data): create a user data abstract class --- packages/atlas-service/src/secret-store.ts | 6 +- .../src/components/diagram-card.spec.tsx | 2 +- .../services/data-model-storage-electron.tsx | 8 ++- .../src/preferences-persistent-storage.ts | 6 +- .../src/user-storage.ts | 6 +- .../src/modules/history-storage.ts | 4 +- packages/compass-user-data/src/index.ts | 2 +- .../compass-user-data/src/user-data.spec.ts | 6 +- packages/compass-user-data/src/user-data.ts | 62 ++++++++++++++++--- .../src/compass-main-connection-storage.ts | 6 +- .../src/compass-pipeline-storage.ts | 6 +- .../src/compass-query-storage.ts | 52 ++++++---------- 12 files changed, 99 insertions(+), 67 deletions(-) diff --git a/packages/atlas-service/src/secret-store.ts b/packages/atlas-service/src/secret-store.ts index 29118af3975..a303151250f 100644 --- a/packages/atlas-service/src/secret-store.ts +++ b/packages/atlas-service/src/secret-store.ts @@ -1,13 +1,13 @@ -import { UserData, z } from '@mongodb-js/compass-user-data'; +import { FileUserData, z } from '@mongodb-js/compass-user-data'; import { safeStorage } from 'electron'; const AtlasPluginStateSchema = z.string().optional(); export class SecretStore { - private readonly userData: UserData; + private readonly userData: FileUserData; private readonly fileName = 'AtlasPluginState'; constructor(basePath?: string) { - this.userData = new UserData(AtlasPluginStateSchema, { + this.userData = new FileUserData(AtlasPluginStateSchema, { subdir: 'AtlasState', basePath, }); diff --git a/packages/compass-data-modeling/src/components/diagram-card.spec.tsx b/packages/compass-data-modeling/src/components/diagram-card.spec.tsx index bd888b75007..f6ee38bd946 100644 --- a/packages/compass-data-modeling/src/components/diagram-card.spec.tsx +++ b/packages/compass-data-modeling/src/components/diagram-card.spec.tsx @@ -42,6 +42,6 @@ describe('DiagramCard', () => { render(); expect(screen.getByText('Test Diagram')).to.be.visible; expect(screen.getByText('someDatabase')).to.be.visible; - expect(screen.getByText('Last modified: October 3, 2023')).to.be.visible; + expect(screen.getByText(/modified/)).to.be.visible; }); }); diff --git a/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx b/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx index 29c23458f3e..fa7a62f77e9 100644 --- a/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx +++ b/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { UserData } from '@mongodb-js/compass-user-data'; +import { FileUserData } from '@mongodb-js/compass-user-data'; import type { DataModelStorage, MongoDBDataModelDescription, @@ -8,9 +8,11 @@ import { MongoDBDataModelDescriptionSchema } from './data-model-storage'; import { DataModelStorageServiceProvider } from '../provider'; class DataModelStorageElectron implements DataModelStorage { - private readonly userData: UserData; + private readonly userData: FileUserData< + typeof MongoDBDataModelDescriptionSchema + >; constructor(basePath?: string) { - this.userData = new UserData(MongoDBDataModelDescriptionSchema, { + this.userData = new FileUserData(MongoDBDataModelDescriptionSchema, { subdir: 'DataModelDescriptions', basePath, }); diff --git a/packages/compass-preferences-model/src/preferences-persistent-storage.ts b/packages/compass-preferences-model/src/preferences-persistent-storage.ts index 4507f7ccacf..2a66dee37d5 100644 --- a/packages/compass-preferences-model/src/preferences-persistent-storage.ts +++ b/packages/compass-preferences-model/src/preferences-persistent-storage.ts @@ -1,4 +1,4 @@ -import { type z, UserData } from '@mongodb-js/compass-user-data'; +import { type z, FileUserData } from '@mongodb-js/compass-user-data'; import { getDefaultsForStoredPreferences, getPreferencesValidator, @@ -20,12 +20,12 @@ export type PreferencesSafeStorage = { export class PersistentStorage implements PreferencesStorage { private readonly file = 'General'; private readonly defaultPreferences = getDefaultsForStoredPreferences(); - private readonly userData: UserData; + private readonly userData: FileUserData; private preferences: StoredPreferences = getDefaultsForStoredPreferences(); private safeStorage?: PreferencesSafeStorage; constructor(basePath?: string, safeStorage?: PreferencesSafeStorage) { - this.userData = new UserData(getPreferencesValidator(), { + this.userData = new FileUserData(getPreferencesValidator(), { subdir: 'AppPreferences', basePath, }); diff --git a/packages/compass-preferences-model/src/user-storage.ts b/packages/compass-preferences-model/src/user-storage.ts index 044d6b04b30..fbaed7f7b27 100644 --- a/packages/compass-preferences-model/src/user-storage.ts +++ b/packages/compass-preferences-model/src/user-storage.ts @@ -1,6 +1,6 @@ import { z } from '@mongodb-js/compass-user-data'; import { UUID } from 'bson'; -import { UserData } from '@mongodb-js/compass-user-data'; +import { FileUserData } from '@mongodb-js/compass-user-data'; const UserSchema = z.object({ id: z.string().uuid(), @@ -24,9 +24,9 @@ export interface UserStorage { } export class UserStorageImpl implements UserStorage { - private readonly userData: UserData; + private readonly userData: FileUserData; constructor(basePath?: string) { - this.userData = new UserData(UserSchema, { + this.userData = new FileUserData(UserSchema, { subdir: 'Users', basePath, }); diff --git a/packages/compass-shell/src/modules/history-storage.ts b/packages/compass-shell/src/modules/history-storage.ts index f302a2cf892..5f1cab73a04 100644 --- a/packages/compass-shell/src/modules/history-storage.ts +++ b/packages/compass-shell/src/modules/history-storage.ts @@ -1,12 +1,12 @@ import { getAppName } from '@mongodb-js/compass-utils'; -import { UserData, z } from '@mongodb-js/compass-user-data'; +import { FileUserData, z } from '@mongodb-js/compass-user-data'; export class HistoryStorage { fileName = 'shell-history'; userData; constructor(basePath?: string) { - this.userData = new UserData(z.string().array(), { + this.userData = new FileUserData(z.string().array(), { // Todo: https://jira.mongodb.org/browse/COMPASS-7080 subdir: getAppName() ?? '', basePath, diff --git a/packages/compass-user-data/src/index.ts b/packages/compass-user-data/src/index.ts index f5b3b57d6bc..b216fd77f99 100644 --- a/packages/compass-user-data/src/index.ts +++ b/packages/compass-user-data/src/index.ts @@ -1,3 +1,3 @@ export type { Stats, ReadAllResult, ReadAllWithStatsResult } from './user-data'; -export { UserData } from './user-data'; +export { IUserData, FileUserData } from './user-data'; export { z } from 'zod'; diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index e1f2ead78cb..155a020092a 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -3,7 +3,7 @@ import { Stats } from 'fs'; import os from 'os'; import path from 'path'; import { expect } from 'chai'; -import { UserData, type UserDataOptions } from './user-data'; +import { FileUserData, type FileUserDataOptions } from './user-data'; import { z, type ZodError } from 'zod'; type ValidatorOptions = { @@ -44,11 +44,11 @@ describe('user-data', function () { const getUserData = ( userDataOpts: Partial< - UserDataOptions>> + FileUserDataOptions>> > = {}, validatorOpts: ValidatorOptions = {} ) => { - return new UserData(getTestSchema(validatorOpts), { + return new FileUserData(getTestSchema(validatorOpts), { subdir, basePath: tmpDir, ...userDataOpts, diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 92d3cd36d5e..7539686c51a 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -12,7 +12,7 @@ type SerializeContent = (content: I) => string; type DeserializeContent = (content: string) => unknown; type GetFileName = (id: string) => string; -export type UserDataOptions = { +export type FileUserDataOptions = { subdir: string; basePath?: string; serialize?: SerializeContent; @@ -20,6 +20,11 @@ export type UserDataOptions = { getFileName?: GetFileName; }; +export type AtlasUserDataOptions = { + serialize?: SerializeContent; + deserialize?: DeserializeContent; +}; + type ReadOptions = { ignoreErrors: boolean; }; @@ -63,28 +68,54 @@ export interface ReadAllWithStatsResult { errors: Error[]; } -export class UserData { +export abstract class IUserData { + protected readonly validator: T; + protected readonly serialize: SerializeContent>; + protected readonly deserialize: DeserializeContent; + protected static readonly semaphore = new Semaphore(100); + + constructor( + validator: T, + { + serialize = (content: z.input) => JSON.stringify(content, null, 2), + deserialize = JSON.parse, + }: { + serialize?: SerializeContent>; + deserialize?: DeserializeContent; + } = {} + ) { + this.validator = validator; + this.serialize = serialize; + this.deserialize = deserialize; + } + + abstract write(id: string, content: z.input): Promise; + abstract delete(id: string): Promise; + abstract readAll(options?: ReadOptions): Promise>; + abstract updateAttributes( + id: string, + data: Partial> + ): Promise>; +} + +export class FileUserData extends IUserData { private readonly subdir: string; private readonly basePath?: string; - private readonly serialize: SerializeContent>; - private readonly deserialize: DeserializeContent; private readonly getFileName: GetFileName; - private readonly semaphore = new Semaphore(100); constructor( - private readonly validator: T, + validator: T, { subdir, basePath, serialize = (content: z.input) => JSON.stringify(content, null, 2), deserialize = JSON.parse, getFileName = (id) => `${id}.json`, - }: UserDataOptions> + }: FileUserDataOptions> ) { + super(validator, { serialize, deserialize }); this.subdir = subdir; this.basePath = basePath; - this.deserialize = deserialize; - this.serialize = serialize; this.getFileName = getFileName; } @@ -126,7 +157,7 @@ export class UserData { let handle: fs.FileHandle | undefined = undefined; let release: (() => void) | undefined = undefined; try { - release = await this.semaphore.waitForRelease(); + release = await IUserData.semaphore.waitForRelease(); handle = await fs.open(absolutePath, 'r'); [stats, data] = await Promise.all([ handle.stat(), @@ -290,4 +321,15 @@ export class UserData { ) { return (await this.readOneWithStats(id, options))?.[0]; } + + async updateAttributes( + id: string, + data: Partial> + ): Promise> { + await this.write(id, { + ...((await this.readOne(id)) ?? {}), + ...data, + }); + return await this.readOne(id); + } } diff --git a/packages/connection-storage/src/compass-main-connection-storage.ts b/packages/connection-storage/src/compass-main-connection-storage.ts index ade7c9e9e6e..78f5380b735 100644 --- a/packages/connection-storage/src/compass-main-connection-storage.ts +++ b/packages/connection-storage/src/compass-main-connection-storage.ts @@ -24,7 +24,7 @@ import type { ImportConnectionOptions, ExportConnectionOptions, } from './import-export-connection'; -import { UserData, z } from '@mongodb-js/compass-user-data'; +import { FileUserData, z } from '@mongodb-js/compass-user-data'; import type { ConnectionStorage, AutoConnectPreferences, @@ -86,7 +86,7 @@ const ConnectionSchema: z.Schema = z .passthrough(); class CompassMainConnectionStorage implements ConnectionStorage { - private readonly userData: UserData; + private readonly userData: FileUserData; private readonly version = 1; private readonly maxAllowedRecentConnections = 10; @@ -95,7 +95,7 @@ class CompassMainConnectionStorage implements ConnectionStorage { private readonly ipcMain: ConnectionStorageIPCMain, basePath?: string ) { - this.userData = new UserData(ConnectionSchema, { + this.userData = new FileUserData(ConnectionSchema, { subdir: 'Connections', basePath, }); diff --git a/packages/my-queries-storage/src/compass-pipeline-storage.ts b/packages/my-queries-storage/src/compass-pipeline-storage.ts index daa5ae362eb..766fc0166a0 100644 --- a/packages/my-queries-storage/src/compass-pipeline-storage.ts +++ b/packages/my-queries-storage/src/compass-pipeline-storage.ts @@ -1,13 +1,13 @@ import type { Stats } from '@mongodb-js/compass-user-data'; -import { UserData } from '@mongodb-js/compass-user-data'; +import { FileUserData } from '@mongodb-js/compass-user-data'; import { PipelineSchema } from './pipeline-storage-schema'; import type { SavedPipeline } from './pipeline-storage-schema'; import type { PipelineStorage } from './pipeline-storage'; export class CompassPipelineStorage implements PipelineStorage { - private readonly userData: UserData; + private readonly userData: FileUserData; constructor(basePath?: string) { - this.userData = new UserData(PipelineSchema, { + this.userData = new FileUserData(PipelineSchema, { subdir: 'SavedPipelines', basePath, }); diff --git a/packages/my-queries-storage/src/compass-query-storage.ts b/packages/my-queries-storage/src/compass-query-storage.ts index e9b6b3b6169..2b1690d77ac 100644 --- a/packages/my-queries-storage/src/compass-query-storage.ts +++ b/packages/my-queries-storage/src/compass-query-storage.ts @@ -1,44 +1,30 @@ import { UUID, EJSON } from 'bson'; -import { UserData, type z } from '@mongodb-js/compass-user-data'; -import { - RecentQuerySchema, - FavoriteQuerySchema, - type RecentQuery, - type FavoriteQuery, -} from './query-storage-schema'; +import { type z } from '@mongodb-js/compass-user-data'; +import { type IUserData, FileUserData } from '@mongodb-js/compass-user-data'; +import { RecentQuerySchema, FavoriteQuerySchema } from './query-storage-schema'; import type { FavoriteQueryStorage, RecentQueryStorage } from './query-storage'; export type QueryStorageOptions = { basepath?: string; }; -export interface QueryStorageBackend { - loadAll(namespace?: string): Promise; - updateAttributes(id: string, data: Partial): Promise; - delete(id: string): Promise; - saveQuery(data: Omit): Promise; -} - -export abstract class CompassQueryStorage< - TSchema extends z.Schema, - TData extends z.output = z.output -> implements QueryStorageBackend -{ - protected readonly userData: UserData; +export abstract class CompassQueryStorage { + protected readonly userData: IUserData; constructor( schemaValidator: TSchema, protected readonly folder: string, protected readonly options: QueryStorageOptions ) { - this.userData = new UserData(schemaValidator, { + // TODO: logic for whether we're in compass web or compass desktop + this.userData = new FileUserData(schemaValidator, { subdir: folder, basePath: options.basepath, serialize: (content) => EJSON.stringify(content, undefined, 2), - deserialize: (content) => EJSON.parse(content), + deserialize: (content: string) => EJSON.parse(content), }); } - async loadAll(namespace?: string): Promise { + async loadAll(namespace?: string): Promise[]> { try { const { data } = await this.userData.readAll(); const sortedData = data @@ -52,23 +38,23 @@ export abstract class CompassQueryStorage< } } - async updateAttributes(id: string, data: Partial): Promise { - await this.userData.write(id, { - ...((await this.userData.readOne(id)) ?? {}), - ...data, - }); - return await this.userData.readOne(id); + async write(id: string, content: z.input): Promise { + return await this.userData.write(id, content); } async delete(id: string) { return await this.userData.delete(id); } - abstract saveQuery(data: any): Promise; + async updateAttributes(id: string, data: Partial>) { + return await this.userData.updateAttributes(id, data); + } + + abstract saveQuery(data: Partial>): Promise; } export class CompassRecentQueryStorage - extends CompassQueryStorage + extends CompassQueryStorage implements RecentQueryStorage { private readonly maxAllowedQueries = 30; @@ -88,6 +74,7 @@ export class CompassRecentQueryStorage } const _id = new UUID().toString(); + // this creates a recent query that we will write to system/db const recentQuery = { ...data, _id, @@ -98,7 +85,7 @@ export class CompassRecentQueryStorage } export class CompassFavoriteQueryStorage - extends CompassQueryStorage + extends CompassQueryStorage implements FavoriteQueryStorage { constructor(options: QueryStorageOptions = {}) { @@ -112,6 +99,7 @@ export class CompassFavoriteQueryStorage > ): Promise { const _id = new UUID().toString(); + // this creates a favorite query that we will write to system/db const favoriteQuery = { ...data, _id, From 701adafffa5b0105bb4e96fae13dd50e80275ea0 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Thu, 10 Jul 2025 14:19:13 -0400 Subject: [PATCH 06/26] fix: rm defaults and add semaphore to FileUserData --- .../src/components/diagram-card.spec.tsx | 2 +- packages/compass-user-data/src/user-data.ts | 8 ++++---- packages/my-queries-storage/src/compass-query-storage.ts | 5 ++++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/compass-data-modeling/src/components/diagram-card.spec.tsx b/packages/compass-data-modeling/src/components/diagram-card.spec.tsx index f6ee38bd946..bd888b75007 100644 --- a/packages/compass-data-modeling/src/components/diagram-card.spec.tsx +++ b/packages/compass-data-modeling/src/components/diagram-card.spec.tsx @@ -42,6 +42,6 @@ describe('DiagramCard', () => { render(); expect(screen.getByText('Test Diagram')).to.be.visible; expect(screen.getByText('someDatabase')).to.be.visible; - expect(screen.getByText(/modified/)).to.be.visible; + expect(screen.getByText('Last modified: October 3, 2023')).to.be.visible; }); }); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 7539686c51a..ec4cad6868f 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -72,7 +72,6 @@ export abstract class IUserData { protected readonly validator: T; protected readonly serialize: SerializeContent>; protected readonly deserialize: DeserializeContent; - protected static readonly semaphore = new Semaphore(100); constructor( validator: T, @@ -102,14 +101,15 @@ export class FileUserData extends IUserData { private readonly subdir: string; private readonly basePath?: string; private readonly getFileName: GetFileName; + protected readonly semaphore = new Semaphore(100); constructor( validator: T, { subdir, basePath, - serialize = (content: z.input) => JSON.stringify(content, null, 2), - deserialize = JSON.parse, + serialize, + deserialize, getFileName = (id) => `${id}.json`, }: FileUserDataOptions> ) { @@ -157,7 +157,7 @@ export class FileUserData extends IUserData { let handle: fs.FileHandle | undefined = undefined; let release: (() => void) | undefined = undefined; try { - release = await IUserData.semaphore.waitForRelease(); + release = await this.semaphore.waitForRelease(); handle = await fs.open(absolutePath, 'r'); [stats, data] = await Promise.all([ handle.stat(), diff --git a/packages/my-queries-storage/src/compass-query-storage.ts b/packages/my-queries-storage/src/compass-query-storage.ts index 2b1690d77ac..c133ee81c53 100644 --- a/packages/my-queries-storage/src/compass-query-storage.ts +++ b/packages/my-queries-storage/src/compass-query-storage.ts @@ -46,7 +46,10 @@ export abstract class CompassQueryStorage { return await this.userData.delete(id); } - async updateAttributes(id: string, data: Partial>) { + async updateAttributes( + id: string, + data: Partial> + ): Promise> { return await this.userData.updateAttributes(id, data); } From daee65a5fbf0f0cbc13dd58de212fb8047590b9e Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Tue, 15 Jul 2025 14:53:09 -0400 Subject: [PATCH 07/26] feat(save-user-data): push for help --- packages/atlas-service/package.json | 2 + packages/compass-global-writes/src/index.ts | 1 + packages/compass-user-data/package.json | 3 + packages/compass-user-data/src/index.ts | 2 +- .../compass-user-data/src/user-data.spec.ts | 109 +++++++++++++ packages/compass-user-data/src/user-data.ts | 144 ++++++++++++++++++ packages/compass-user-data/tsconfig.json | 3 +- 7 files changed, 262 insertions(+), 2 deletions(-) diff --git a/packages/atlas-service/package.json b/packages/atlas-service/package.json index 09cfdb5a504..b3d84b58b50 100644 --- a/packages/atlas-service/package.json +++ b/packages/atlas-service/package.json @@ -28,11 +28,13 @@ ], "license": "SSPL", "exports": { + "./atlas-service": "./dist/atlas-service.js", "./main": "./main.js", "./renderer": "./renderer.js", "./provider": "./dist/provider.js" }, "compass:exports": { + "./atlas-service": "./src/atlas-service.ts", "./main": "./src/main.ts", "./renderer": "./src/renderer.ts", "./provider": "./src/provider.tsx" diff --git a/packages/compass-global-writes/src/index.ts b/packages/compass-global-writes/src/index.ts index 2a02dadad29..d908439c4b3 100644 --- a/packages/compass-global-writes/src/index.ts +++ b/packages/compass-global-writes/src/index.ts @@ -8,6 +8,7 @@ import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; import { atlasServiceLocator } from '@mongodb-js/atlas-service/provider'; +export { AtlasGlobalWritesService } from './services/atlas-global-writes-service'; const CompassGlobalWritesPluginProvider = registerCompassPlugin( { diff --git a/packages/compass-user-data/package.json b/packages/compass-user-data/package.json index 3d6d4633ac8..a1ee4b67d6d 100644 --- a/packages/compass-user-data/package.json +++ b/packages/compass-user-data/package.json @@ -51,6 +51,9 @@ "dependencies": { "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", + "@mongodb-js/atlas-service": "^0.49.0", + "@mongodb-js/compass-connections": "^0.31.0", + "compass-preferences-model": "^2.44.0", "write-file-atomic": "^5.0.1", "zod": "^3.25.17" }, diff --git a/packages/compass-user-data/src/index.ts b/packages/compass-user-data/src/index.ts index b216fd77f99..777475986fa 100644 --- a/packages/compass-user-data/src/index.ts +++ b/packages/compass-user-data/src/index.ts @@ -1,3 +1,3 @@ export type { Stats, ReadAllResult, ReadAllWithStatsResult } from './user-data'; -export { IUserData, FileUserData } from './user-data'; +export { IUserData, FileUserData, AtlasUserData } from './user-data'; export { z } from 'zod'; diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index 155a020092a..df6bbe4ee08 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -418,3 +418,112 @@ describe('user-data', function () { }); }); }); + +describe('AtlasUserData', function () { + let AtlasUserData: any; + let atlasServiceMock: any; + let validator: any; + let instance: any; + + before(async function () { + // Dynamically import AtlasUserData to avoid circular deps + const module = await import('./user-data'); + AtlasUserData = module.AtlasUserData; + validator = getTestSchema(); + }); + + beforeEach(function () { + atlasServiceMock = { + authenticatedFetch: sinon.stub(), + }; + instance = new AtlasUserData(validator, atlasServiceMock, { + groupId: 'test-group', + projectId: 'test-project', + endpoint: '/api/user-data', + }); + }); + + it('constructs with dependencies', function () { + expect(instance).to.have.property('atlasService', atlasServiceMock); + expect(instance).to.have.property('groupId', 'test-group'); + expect(instance).to.have.property('projectId', 'test-project'); + expect(instance).to.have.property('endpoint', '/api/user-data'); + }); + + it('write: calls authenticatedFetch and validates response', async function () { + const item = { name: 'Atlas', hasDarkMode: false }; + atlasServiceMock.authenticatedFetch.resolves({ + ok: true, + json: async () => await Promise.resolve(item), + }); + const result = await instance.write('id1', item); + expect(result).to.be.true; + expect(atlasServiceMock.authenticatedFetch.calledOnce).to.be.true; + }); + + it('write: handles API error', async function () { + atlasServiceMock.authenticatedFetch.resolves({ ok: false, status: 500 }); + const result = await instance.write('id1', { name: 'Atlas' }); + expect(result).to.be.false; + }); + + it('delete: calls authenticatedFetch and returns true on success', async function () { + atlasServiceMock.authenticatedFetch.resolves({ ok: true }); + const result = await instance.delete('id1'); + expect(result).to.be.true; + }); + + it('delete: returns false on API failure', async function () { + atlasServiceMock.authenticatedFetch.resolves({ ok: false }); + const result = await instance.delete('id1'); + expect(result).to.be.false; + }); + + it('readAll: returns validated items from API', async function () { + const items = [ + { name: 'Atlas', hasDarkMode: true }, + { name: 'Compass', hasDarkMode: false }, + ]; + atlasServiceMock.authenticatedFetch.resolves({ + ok: true, + json: async () => await Promise.resolve(items), + }); + const result = await instance.readAll(); + expect(result.data).to.have.lengthOf(2); + expect(result.errors).to.have.lengthOf(0); + expect(result.data[0]).to.have.property('name'); + }); + + it('readAll: returns errors for invalid items', async function () { + const items = [ + { name: 'Atlas', hasDarkMode: 'not-a-bool' }, + { name: 'Compass', hasDarkMode: false }, + ]; + atlasServiceMock.authenticatedFetch.resolves({ + ok: true, + json: async () => await Promise.resolve(items), + }); + const result = await instance.readAll(); + expect(result.data).to.have.lengthOf(1); + expect(result.errors).to.have.lengthOf(1); + }); + + it('updateAttributes: calls authenticatedFetch and validates response', async function () { + const attrs = { hasDarkMode: false }; + atlasServiceMock.authenticatedFetch.resolves({ + ok: true, + json: async () => + await Promise.resolve({ name: 'Atlas', hasDarkMode: false }), + }); + const result = await instance.updateAttributes('id1', attrs); + expect(result).to.deep.equal({ name: 'Atlas', hasDarkMode: false }); + }); + + it('updateAttributes: returns undefined on API error', async function () { + atlasServiceMock.authenticatedFetch.resolves({ ok: false }); + const result = await instance.updateAttributes('id1', { + hasDarkMode: true, + }); + expect(result).to.be.undefined; + }); +}); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index ec4cad6868f..ed89d5e75cf 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -5,6 +5,10 @@ import { getStoragePath } from '@mongodb-js/compass-utils'; import type { z } from 'zod'; import writeFile from 'write-file-atomic'; import { Semaphore } from './semaphore'; +import { AtlasService } from '@mongodb-js/atlas-service/atlas-service'; +import { atlasAuthServiceLocator } from '@mongodb-js/atlas-service/provider'; +import { preferencesLocator } from 'compass-preferences-model/provider'; +import { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; const { log, mongoLogId } = createLogger('COMPASS-USER-STORAGE'); @@ -333,3 +337,143 @@ export class FileUserData extends IUserData { return await this.readOne(id); } } + +// TODO: update endpoints to reflect the merged api endpoints +export class AtlasUserData extends IUserData { + private atlasService: AtlasService; + private readonly preferences = preferencesLocator(); + // private readonly preferences = null; + private readonly connectionInfoRef = connectionInfoRefLocator(); + // private readonly connectionInfoRef = null; + private readonly logger = createLogger('ATLAS-USER-STORAGE'); + private readonly groupId = + this.connectionInfoRef?.current?.atlasMetadata?.projectId; + private readonly orgId = + this.connectionInfoRef?.current?.atlasMetadata?.orgId; + // should this BASE_URL be a parameter passed to the constructor? + // this might make future usage of this code easier, if we want to call a different endpoint + private readonly BASE_URL = 'cluster-connection.cloud-local.mongodb.com'; + constructor( + validator: T, + { serialize, deserialize }: AtlasUserDataOptions> + ) { + super(validator, { serialize, deserialize }); + const authService = atlasAuthServiceLocator(); + // const authService = null; + const options = {}; + + this.atlasService = new AtlasService( + authService, + this.preferences, + this.logger, + options + ); + this.atlasService = null; + } + + async write(id: string, content: z.input): Promise { + this.validator.parse(content); + + // do not need to use id because content already contains the id + const response = await this.atlasService.authenticatedFetch(this.getUrl(), { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + id: id, + data: this.serialize(content), + createdAt: new Date(), + groupId: this.groupId, + }), + }); + // TODO: fix this error handling, should fit current compass needs + if (!response.ok) { + throw new Error( + `Failed to post data: ${response.status} ${response.statusText}` + ); + } + return true; + } + + async delete(id: string): Promise { + const response = await this.atlasService.authenticatedFetch( + this.getUrl() + `/${id}`, + { + method: 'DELETE', + } + ); + if (!response.ok) { + throw new Error( + `Failed to delete data: ${response.status} ${response.statusText}` + ); + } + return true; + } + + async readAll(): Promise> { + try { + const response = await this.atlasService.authenticatedFetch( + this.getUrl(), + { + method: 'GET', + headers: { + accept: 'application/json', + }, + } + ); + // TODO: fix this error handling, should fit current compass needs + if (!response.ok) { + throw new Error( + `Failed to get data: ${response.status} ${response.statusText}` + ); + } + const json = await response.json(); + const data = Array.isArray(json) + ? json.map((item) => + this.validator.parse(this.deserialize(item.data as string)) + ) + : []; + return { data, errors: [] }; + } catch (error) { + return { data: [], errors: [error as Error] }; + } + } + + async updateAttributes( + id: string, + data: Partial> + ): Promise> { + const response = await this.atlasService.authenticatedFetch( + this.getUrl() + `/${id}`, + { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + // TODO: not sure whether currently compass sometimes adds to data or always replaces it + // figure out if we should get all data, find specific query by id, then update using JS + body: this.serialize(data), + } + ); + if (!response.ok) { + throw new Error( + `Failed to update data: ${response.status} ${response.statusText}` + ); + } + const json = await response.json(); + // TODO: fix this, currently endpoint does not return the updated data + // so we need to decide whether this is necessary + return this.validator.parse(json.data); + } + + private getUrl() { + // if (endpoint.startsWith('/')) { + // endpoint = endpoint.slice(1); + // } + // if (endpoint.endsWith('/')) { + // endpoint = endpoint.slice(0, -1); + // } + return `${this.BASE_URL}/queries/favorites/${this.orgId}/${this.groupId}`; + } +} diff --git a/packages/compass-user-data/tsconfig.json b/packages/compass-user-data/tsconfig.json index ecd0a14474a..75250566a5d 100644 --- a/packages/compass-user-data/tsconfig.json +++ b/packages/compass-user-data/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "@mongodb-js/tsconfig-compass/tsconfig.common.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + "skipLibCheck": true }, "include": ["src/**/*"], "exclude": ["./src/**/*.spec.*"] From 90573c710ac925109bac81b34ddc43cc0fa764e6 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Tue, 15 Jul 2025 15:41:58 -0400 Subject: [PATCH 08/26] feat(save-user-data): comment out nulls --- package-lock.json | 6 ++++++ packages/compass-user-data/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index c5a09a2724a..0841986555c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47429,8 +47429,11 @@ "version": "0.7.5", "license": "SSPL", "dependencies": { + "@mongodb-js/atlas-service": "^0.49.0", + "@mongodb-js/compass-connections": "^1.64.0", "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", + "compass-preferences-model": "^2.44.0", "write-file-atomic": "^5.0.1", "zod": "^3.25.17" }, @@ -59073,6 +59076,8 @@ "@mongodb-js/compass-user-data": { "version": "file:packages/compass-user-data", "requires": { + "@mongodb-js/atlas-service": "^0.49.0", + "@mongodb-js/compass-connections": "^1.64.0", "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", "@mongodb-js/eslint-config-compass": "^1.4.1", @@ -59084,6 +59089,7 @@ "@types/sinon-chai": "^3.2.5", "@types/write-file-atomic": "^4.0.1", "chai": "^4.3.6", + "compass-preferences-model": "^2.44.0", "depcheck": "^1.4.1", "gen-esm-wrapper": "^1.1.0", "mocha": "^10.2.0", diff --git a/packages/compass-user-data/package.json b/packages/compass-user-data/package.json index a1ee4b67d6d..9c17a8279c0 100644 --- a/packages/compass-user-data/package.json +++ b/packages/compass-user-data/package.json @@ -52,7 +52,7 @@ "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", "@mongodb-js/atlas-service": "^0.49.0", - "@mongodb-js/compass-connections": "^0.31.0", + "@mongodb-js/compass-connections": "^1.64.0", "compass-preferences-model": "^2.44.0", "write-file-atomic": "^5.0.1", "zod": "^3.25.17" From 5edf5e2e3621bdd0b494db638d5abd2d738433b1 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Thu, 17 Jul 2025 10:34:57 -0400 Subject: [PATCH 09/26] potentital org and group id retrieval --- package-lock.json | 472 +++++++++++++++++- packages/atlas-service/package.json | 2 - packages/compass-global-writes/src/index.ts | 1 - .../src/stores/query-bar-store.ts | 6 + packages/compass-user-data/package.json | 10 +- packages/compass-user-data/src/index.ts | 2 +- .../compass-user-data/src/user-data.spec.ts | 216 ++++---- packages/compass-user-data/src/user-data.ts | 86 ++-- packages/compass-user-data/tsconfig.json | 3 +- .../src/compass-query-storage.ts | 6 + .../my-queries-storage/src/query-storage.ts | 1 + 11 files changed, 623 insertions(+), 182 deletions(-) diff --git a/package-lock.json b/package-lock.json index f4b148ab6f7..cdff91ba303 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43687,6 +43687,18 @@ "typescript": "^5.8.3" } }, + "packages/atlas-service/node_modules/@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "license": "SSPL", + "dependencies": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, "packages/atlas-service/node_modules/@mongodb-js/devtools-connect": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.9.2.tgz", @@ -43720,6 +43732,18 @@ "node": ">=0.3.1" } }, + "packages/atlas-service/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/atlas-service/node_modules/sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -43738,6 +43762,28 @@ "url": "https://opencollective.com/sinon" } }, + "packages/atlas-service/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "packages/atlas-service/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "packages/bson-transpilers": { "version": "3.2.13", "license": "SSPL", @@ -45032,6 +45078,18 @@ "xvfb-maybe": "^0.2.1" } }, + "packages/compass-data-modeling/node_modules/@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "license": "SSPL", + "dependencies": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, "packages/compass-data-modeling/node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -45102,6 +45160,18 @@ "dev": true, "license": "MIT" }, + "packages/compass-data-modeling/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/compass-data-modeling/node_modules/sinon": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", @@ -45121,6 +45191,28 @@ "url": "https://opencollective.com/sinon" } }, + "packages/compass-data-modeling/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "packages/compass-data-modeling/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "packages/compass-database": { "name": "@mongodb-js/compass-database", "version": "3.19.1", @@ -46807,6 +46899,30 @@ "sinon": "^9.2.3" } }, + "packages/compass-preferences-model/node_modules/@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "license": "SSPL", + "dependencies": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, + "packages/compass-preferences-model/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/compass-preferences-model/node_modules/sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -46834,6 +46950,19 @@ "node": ">=0.3.1" } }, + "packages/compass-preferences-model/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "packages/compass-preferences-model/node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", @@ -46842,6 +46971,15 @@ "node": ">=12" } }, + "packages/compass-preferences-model/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "packages/compass-query-bar": { "name": "@mongodb-js/compass-query-bar", "version": "8.66.0", @@ -47380,6 +47518,52 @@ "typescript": "^5.8.3" } }, + "packages/compass-shell/node_modules/@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "license": "SSPL", + "dependencies": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, + "packages/compass-shell/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/compass-shell/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "packages/compass-shell/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "packages/compass-sidebar": { "name": "@mongodb-js/compass-sidebar", "version": "5.65.0", @@ -47724,20 +47908,18 @@ }, "packages/compass-user-data": { "name": "@mongodb-js/compass-user-data", - "version": "0.8.0", + "version": "0.7.5", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.49.0", - "@mongodb-js/compass-connections": "^1.64.0", + "@mongodb-js/compass-connections": "^1.65.0", "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", - "compass-preferences-model": "^2.44.0", "write-file-atomic": "^5.0.1", "zod": "^3.25.17" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.4.2", - "@mongodb-js/mocha-config-compass": "^1.6.10", + "@mongodb-js/eslint-config-compass": "^1.4.1", + "@mongodb-js/mocha-config-compass": "^1.6.9", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/tsconfig-compass": "^1.2.9", "@types/chai": "^4.2.21", @@ -48748,6 +48930,18 @@ "typescript": "^5.8.3" } }, + "packages/connection-storage/node_modules/@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "license": "SSPL", + "dependencies": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, "packages/connection-storage/node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -48757,6 +48951,18 @@ "node": ">=0.3.1" } }, + "packages/connection-storage/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/connection-storage/node_modules/sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -48775,6 +48981,28 @@ "url": "https://opencollective.com/sinon" } }, + "packages/connection-storage/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "packages/connection-storage/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "packages/data-service": { "name": "mongodb-data-service", "version": "22.29.0", @@ -50391,6 +50619,18 @@ "typescript": "^5.8.3" } }, + "packages/my-queries-storage/node_modules/@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "license": "SSPL", + "dependencies": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, "packages/my-queries-storage/node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -50400,6 +50640,18 @@ "node": ">=0.3.1" } }, + "packages/my-queries-storage/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/my-queries-storage/node_modules/sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -50419,6 +50671,28 @@ "url": "https://opencollective.com/sinon" } }, + "packages/my-queries-storage/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "packages/my-queries-storage/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "packages/notary-service-client": { "name": "@mongodb-js/mongodb-notary-service-client", "version": "2.0.4", @@ -56332,6 +56606,17 @@ "typescript": "^5.8.3" }, "dependencies": { + "@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "requires": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, "@mongodb-js/devtools-connect": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.9.2.tgz", @@ -56354,6 +56639,11 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, "sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -56367,6 +56657,20 @@ "nise": "^4.0.4", "supports-color": "^7.1.0" } + }, + "write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + }, + "zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, @@ -57338,6 +57642,17 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { + "@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "requires": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, "@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -57400,6 +57715,11 @@ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "dev": true }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, "sinon": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", @@ -57413,6 +57733,20 @@ "nise": "^5.1.5", "supports-color": "^7.2.0" } + }, + "write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + }, + "zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, @@ -59057,6 +59391,38 @@ "redux": "^4.2.1", "redux-thunk": "^2.4.2", "typescript": "^5.8.3" + }, + "dependencies": { + "@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "requires": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, + "write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + }, + "zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" + } } }, "@mongodb-js/compass-sidebar": { @@ -59356,8 +59722,7 @@ "@mongodb-js/compass-user-data": { "version": "file:packages/compass-user-data", "requires": { - "@mongodb-js/atlas-service": "^0.49.0", - "@mongodb-js/compass-connections": "^1.64.0", + "@mongodb-js/compass-connections": "^1.65.0", "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", "@mongodb-js/eslint-config-compass": "^1.4.1", @@ -59369,7 +59734,6 @@ "@types/sinon-chai": "^3.2.5", "@types/write-file-atomic": "^4.0.1", "chai": "^4.3.6", - "compass-preferences-model": "^2.44.0", "depcheck": "^1.4.1", "gen-esm-wrapper": "^1.1.0", "mocha": "^10.2.0", @@ -60122,12 +60486,28 @@ "typescript": "^5.8.3" }, "dependencies": { + "@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "requires": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, "sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -60141,6 +60521,20 @@ "nise": "^4.0.4", "supports-color": "^7.1.0" } + }, + "write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + }, + "zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, @@ -60882,12 +61276,28 @@ "typescript": "^5.8.3" }, "dependencies": { + "@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "requires": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, "sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -60901,6 +61311,20 @@ "nise": "^4.0.4", "supports-color": "^7.1.0" } + }, + "write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + }, + "zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, @@ -69185,6 +69609,22 @@ "yargs-parser": "^21.1.1" }, "dependencies": { + "@mongodb-js/compass-user-data": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", + "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", + "requires": { + "@mongodb-js/compass-logging": "^1.7.6", + "@mongodb-js/compass-utils": "^0.9.5", + "write-file-atomic": "^5.0.1", + "zod": "^3.25.17" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, "sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -69207,10 +69647,24 @@ } } }, + "write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + }, "yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + }, + "zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, diff --git a/packages/atlas-service/package.json b/packages/atlas-service/package.json index a0f7fb0356a..65d8b62a1bc 100644 --- a/packages/atlas-service/package.json +++ b/packages/atlas-service/package.json @@ -28,13 +28,11 @@ ], "license": "SSPL", "exports": { - "./atlas-service": "./dist/atlas-service.js", "./main": "./main.js", "./renderer": "./renderer.js", "./provider": "./dist/provider.js" }, "compass:exports": { - "./atlas-service": "./src/atlas-service.ts", "./main": "./src/main.ts", "./renderer": "./src/renderer.ts", "./provider": "./src/provider.tsx" diff --git a/packages/compass-global-writes/src/index.ts b/packages/compass-global-writes/src/index.ts index d908439c4b3..2a02dadad29 100644 --- a/packages/compass-global-writes/src/index.ts +++ b/packages/compass-global-writes/src/index.ts @@ -8,7 +8,6 @@ import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; import { atlasServiceLocator } from '@mongodb-js/atlas-service/provider'; -export { AtlasGlobalWritesService } from './services/atlas-global-writes-service'; const CompassGlobalWritesPluginProvider = registerCompassPlugin( { diff --git a/packages/compass-query-bar/src/stores/query-bar-store.ts b/packages/compass-query-bar/src/stores/query-bar-store.ts index 62f2b7e7018..552045e6936 100644 --- a/packages/compass-query-bar/src/stores/query-bar-store.ts +++ b/packages/compass-query-bar/src/stores/query-bar-store.ts @@ -130,6 +130,12 @@ export function activatePlugin( const favoriteQueryStorage = favoriteQueryStorageAccess?.getStorage(); const recentQueryStorage = recentQueryStorageAccess?.getStorage(); + + const orgId = connectionInfoRef.current.atlasMetadata.orgId; + const groupId = connectionInfoRef.current.atlasMetadata.projectId; + favoriteQueryStorage.setOrgAndGroupId(orgId, groupId); + recentQueryStorage.setOrgAndGroupId(orgId, groupId); + const store = configureStore( { namespace: namespace ?? '', diff --git a/packages/compass-user-data/package.json b/packages/compass-user-data/package.json index ef3ff6ff526..c46990f9be3 100644 --- a/packages/compass-user-data/package.json +++ b/packages/compass-user-data/package.json @@ -12,7 +12,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.8.0", + "version": "0.7.5", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -51,15 +51,13 @@ "dependencies": { "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", - "@mongodb-js/atlas-service": "^0.49.0", - "@mongodb-js/compass-connections": "^1.64.0", - "compass-preferences-model": "^2.44.0", + "@mongodb-js/compass-connections": "^1.65.0", "write-file-atomic": "^5.0.1", "zod": "^3.25.17" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.4.2", - "@mongodb-js/mocha-config-compass": "^1.6.10", + "@mongodb-js/eslint-config-compass": "^1.4.1", + "@mongodb-js/mocha-config-compass": "^1.6.9", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/tsconfig-compass": "^1.2.9", "@types/chai": "^4.2.21", diff --git a/packages/compass-user-data/src/index.ts b/packages/compass-user-data/src/index.ts index 777475986fa..b216fd77f99 100644 --- a/packages/compass-user-data/src/index.ts +++ b/packages/compass-user-data/src/index.ts @@ -1,3 +1,3 @@ export type { Stats, ReadAllResult, ReadAllWithStatsResult } from './user-data'; -export { IUserData, FileUserData, AtlasUserData } from './user-data'; +export { IUserData, FileUserData } from './user-data'; export { z } from 'zod'; diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index df6bbe4ee08..f39ea917964 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -419,111 +419,111 @@ describe('user-data', function () { }); }); -describe('AtlasUserData', function () { - let AtlasUserData: any; - let atlasServiceMock: any; - let validator: any; - let instance: any; - - before(async function () { - // Dynamically import AtlasUserData to avoid circular deps - const module = await import('./user-data'); - AtlasUserData = module.AtlasUserData; - validator = getTestSchema(); - }); - - beforeEach(function () { - atlasServiceMock = { - authenticatedFetch: sinon.stub(), - }; - instance = new AtlasUserData(validator, atlasServiceMock, { - groupId: 'test-group', - projectId: 'test-project', - endpoint: '/api/user-data', - }); - }); - - it('constructs with dependencies', function () { - expect(instance).to.have.property('atlasService', atlasServiceMock); - expect(instance).to.have.property('groupId', 'test-group'); - expect(instance).to.have.property('projectId', 'test-project'); - expect(instance).to.have.property('endpoint', '/api/user-data'); - }); - - it('write: calls authenticatedFetch and validates response', async function () { - const item = { name: 'Atlas', hasDarkMode: false }; - atlasServiceMock.authenticatedFetch.resolves({ - ok: true, - json: async () => await Promise.resolve(item), - }); - const result = await instance.write('id1', item); - expect(result).to.be.true; - expect(atlasServiceMock.authenticatedFetch.calledOnce).to.be.true; - }); - - it('write: handles API error', async function () { - atlasServiceMock.authenticatedFetch.resolves({ ok: false, status: 500 }); - const result = await instance.write('id1', { name: 'Atlas' }); - expect(result).to.be.false; - }); - - it('delete: calls authenticatedFetch and returns true on success', async function () { - atlasServiceMock.authenticatedFetch.resolves({ ok: true }); - const result = await instance.delete('id1'); - expect(result).to.be.true; - }); - - it('delete: returns false on API failure', async function () { - atlasServiceMock.authenticatedFetch.resolves({ ok: false }); - const result = await instance.delete('id1'); - expect(result).to.be.false; - }); - - it('readAll: returns validated items from API', async function () { - const items = [ - { name: 'Atlas', hasDarkMode: true }, - { name: 'Compass', hasDarkMode: false }, - ]; - atlasServiceMock.authenticatedFetch.resolves({ - ok: true, - json: async () => await Promise.resolve(items), - }); - const result = await instance.readAll(); - expect(result.data).to.have.lengthOf(2); - expect(result.errors).to.have.lengthOf(0); - expect(result.data[0]).to.have.property('name'); - }); - - it('readAll: returns errors for invalid items', async function () { - const items = [ - { name: 'Atlas', hasDarkMode: 'not-a-bool' }, - { name: 'Compass', hasDarkMode: false }, - ]; - atlasServiceMock.authenticatedFetch.resolves({ - ok: true, - json: async () => await Promise.resolve(items), - }); - const result = await instance.readAll(); - expect(result.data).to.have.lengthOf(1); - expect(result.errors).to.have.lengthOf(1); - }); - - it('updateAttributes: calls authenticatedFetch and validates response', async function () { - const attrs = { hasDarkMode: false }; - atlasServiceMock.authenticatedFetch.resolves({ - ok: true, - json: async () => - await Promise.resolve({ name: 'Atlas', hasDarkMode: false }), - }); - const result = await instance.updateAttributes('id1', attrs); - expect(result).to.deep.equal({ name: 'Atlas', hasDarkMode: false }); - }); - - it('updateAttributes: returns undefined on API error', async function () { - atlasServiceMock.authenticatedFetch.resolves({ ok: false }); - const result = await instance.updateAttributes('id1', { - hasDarkMode: true, - }); - expect(result).to.be.undefined; - }); -}); +// describe('AtlasUserData', function () { +// let AtlasUserData: any; +// let atlasServiceMock: any; +// let validator: any; +// let instance: any; + +// before(async function () { +// // Dynamically import AtlasUserData to avoid circular deps +// const module = await import('./user-data'); +// AtlasUserData = module.AtlasUserData; +// validator = getTestSchema(); +// }); + +// beforeEach(function () { +// atlasServiceMock = { +// authenticatedFetch: sinon.stub(), +// }; +// instance = new AtlasUserData(validator, atlasServiceMock, { +// groupId: 'test-group', +// projectId: 'test-project', +// endpoint: '/api/user-data', +// }); +// }); + +// it('constructs with dependencies', function () { +// expect(instance).to.have.property('atlasService', atlasServiceMock); +// expect(instance).to.have.property('groupId', 'test-group'); +// expect(instance).to.have.property('projectId', 'test-project'); +// expect(instance).to.have.property('endpoint', '/api/user-data'); +// }); + +// it('write: calls authenticatedFetch and validates response', async function () { +// const item = { name: 'Atlas', hasDarkMode: false }; +// atlasServiceMock.authenticatedFetch.resolves({ +// ok: true, +// json: async () => await Promise.resolve(item), +// }); +// const result = await instance.write('id1', item); +// expect(result).to.be.true; +// expect(atlasServiceMock.authenticatedFetch.calledOnce).to.be.true; +// }); + +// it('write: handles API error', async function () { +// atlasServiceMock.authenticatedFetch.resolves({ ok: false, status: 500 }); +// const result = await instance.write('id1', { name: 'Atlas' }); +// expect(result).to.be.false; +// }); + +// it('delete: calls authenticatedFetch and returns true on success', async function () { +// atlasServiceMock.authenticatedFetch.resolves({ ok: true }); +// const result = await instance.delete('id1'); +// expect(result).to.be.true; +// }); + +// it('delete: returns false on API failure', async function () { +// atlasServiceMock.authenticatedFetch.resolves({ ok: false }); +// const result = await instance.delete('id1'); +// expect(result).to.be.false; +// }); + +// it('readAll: returns validated items from API', async function () { +// const items = [ +// { name: 'Atlas', hasDarkMode: true }, +// { name: 'Compass', hasDarkMode: false }, +// ]; +// atlasServiceMock.authenticatedFetch.resolves({ +// ok: true, +// json: async () => await Promise.resolve(items), +// }); +// const result = await instance.readAll(); +// expect(result.data).to.have.lengthOf(2); +// expect(result.errors).to.have.lengthOf(0); +// expect(result.data[0]).to.have.property('name'); +// }); + +// it('readAll: returns errors for invalid items', async function () { +// const items = [ +// { name: 'Atlas', hasDarkMode: 'not-a-bool' }, +// { name: 'Compass', hasDarkMode: false }, +// ]; +// atlasServiceMock.authenticatedFetch.resolves({ +// ok: true, +// json: async () => await Promise.resolve(items), +// }); +// const result = await instance.readAll(); +// expect(result.data).to.have.lengthOf(1); +// expect(result.errors).to.have.lengthOf(1); +// }); + +// it('updateAttributes: calls authenticatedFetch and validates response', async function () { +// const attrs = { hasDarkMode: false }; +// atlasServiceMock.authenticatedFetch.resolves({ +// ok: true, +// json: async () => +// await Promise.resolve({ name: 'Atlas', hasDarkMode: false }), +// }); +// const result = await instance.updateAttributes('id1', attrs); +// expect(result).to.deep.equal({ name: 'Atlas', hasDarkMode: false }); +// }); + +// it('updateAttributes: returns undefined on API error', async function () { +// atlasServiceMock.authenticatedFetch.resolves({ ok: false }); +// const result = await instance.updateAttributes('id1', { +// hasDarkMode: true, +// }); +// expect(result).to.be.undefined; +// }); +// }); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index ed89d5e75cf..c183dca7006 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -5,10 +5,7 @@ import { getStoragePath } from '@mongodb-js/compass-utils'; import type { z } from 'zod'; import writeFile from 'write-file-atomic'; import { Semaphore } from './semaphore'; -import { AtlasService } from '@mongodb-js/atlas-service/atlas-service'; -import { atlasAuthServiceLocator } from '@mongodb-js/atlas-service/provider'; -import { preferencesLocator } from 'compass-preferences-model/provider'; -import { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; +// import { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; const { log, mongoLogId } = createLogger('COMPASS-USER-STORAGE'); @@ -340,42 +337,29 @@ export class FileUserData extends IUserData { // TODO: update endpoints to reflect the merged api endpoints export class AtlasUserData extends IUserData { - private atlasService: AtlasService; - private readonly preferences = preferencesLocator(); - // private readonly preferences = null; - private readonly connectionInfoRef = connectionInfoRefLocator(); - // private readonly connectionInfoRef = null; - private readonly logger = createLogger('ATLAS-USER-STORAGE'); - private readonly groupId = - this.connectionInfoRef?.current?.atlasMetadata?.projectId; - private readonly orgId = - this.connectionInfoRef?.current?.atlasMetadata?.orgId; + private readonly authenticatedFetch; // should this BASE_URL be a parameter passed to the constructor? // this might make future usage of this code easier, if we want to call a different endpoint + private readonly orgId; + private readonly groupId; private readonly BASE_URL = 'cluster-connection.cloud-local.mongodb.com'; constructor( validator: T, + authenticatedFetch: ( + url: RequestInfo | URL, + options?: RequestInit + ) => Promise, { serialize, deserialize }: AtlasUserDataOptions> ) { super(validator, { serialize, deserialize }); - const authService = atlasAuthServiceLocator(); - // const authService = null; - const options = {}; - - this.atlasService = new AtlasService( - authService, - this.preferences, - this.logger, - options - ); - this.atlasService = null; + this.authenticatedFetch = authenticatedFetch; } async write(id: string, content: z.input): Promise { this.validator.parse(content); // do not need to use id because content already contains the id - const response = await this.atlasService.authenticatedFetch(this.getUrl(), { + const response = await this.authenticatedFetch(this.getUrl(), { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -397,12 +381,9 @@ export class AtlasUserData extends IUserData { } async delete(id: string): Promise { - const response = await this.atlasService.authenticatedFetch( - this.getUrl() + `/${id}`, - { - method: 'DELETE', - } - ); + const response = await this.authenticatedFetch(this.getUrl() + `/${id}`, { + method: 'DELETE', + }); if (!response.ok) { throw new Error( `Failed to delete data: ${response.status} ${response.statusText}` @@ -413,15 +394,12 @@ export class AtlasUserData extends IUserData { async readAll(): Promise> { try { - const response = await this.atlasService.authenticatedFetch( - this.getUrl(), - { - method: 'GET', - headers: { - accept: 'application/json', - }, - } - ); + const response = await this.authenticatedFetch(this.getUrl(), { + method: 'GET', + headers: { + accept: 'application/json', + }, + }); // TODO: fix this error handling, should fit current compass needs if (!response.ok) { throw new Error( @@ -444,18 +422,15 @@ export class AtlasUserData extends IUserData { id: string, data: Partial> ): Promise> { - const response = await this.atlasService.authenticatedFetch( - this.getUrl() + `/${id}`, - { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - // TODO: not sure whether currently compass sometimes adds to data or always replaces it - // figure out if we should get all data, find specific query by id, then update using JS - body: this.serialize(data), - } - ); + const response = await this.authenticatedFetch(this.getUrl() + `/${id}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + // TODO: not sure whether currently compass sometimes adds to data or always replaces it + // figure out if we should get all data, find specific query by id, then update using JS + body: this.serialize(data), + }); if (!response.ok) { throw new Error( `Failed to update data: ${response.status} ${response.statusText}` @@ -467,6 +442,11 @@ export class AtlasUserData extends IUserData { return this.validator.parse(json.data); } + setOrgAndGroupId(orgId: string, groupId: string): void { + this.orgId = orgId; + this.groupId = groupId; + } + private getUrl() { // if (endpoint.startsWith('/')) { // endpoint = endpoint.slice(1); diff --git a/packages/compass-user-data/tsconfig.json b/packages/compass-user-data/tsconfig.json index 75250566a5d..ecd0a14474a 100644 --- a/packages/compass-user-data/tsconfig.json +++ b/packages/compass-user-data/tsconfig.json @@ -1,8 +1,7 @@ { "extends": "@mongodb-js/tsconfig-compass/tsconfig.common.json", "compilerOptions": { - "outDir": "dist", - "skipLibCheck": true + "outDir": "dist" }, "include": ["src/**/*"], "exclude": ["./src/**/*.spec.*"] diff --git a/packages/my-queries-storage/src/compass-query-storage.ts b/packages/my-queries-storage/src/compass-query-storage.ts index c133ee81c53..3856366cbd4 100644 --- a/packages/my-queries-storage/src/compass-query-storage.ts +++ b/packages/my-queries-storage/src/compass-query-storage.ts @@ -53,6 +53,12 @@ export abstract class CompassQueryStorage { return await this.userData.updateAttributes(id, data); } + setOrgAndGroupId(orgId: string, groupId: string): void { + if (this.userData instanceof AtlasUserData) { + this.userData.setOrgAndGroupId(orgId, groupId); + } + } + abstract saveQuery(data: Partial>): Promise; } diff --git a/packages/my-queries-storage/src/query-storage.ts b/packages/my-queries-storage/src/query-storage.ts index a932e0a46d5..7d15994453e 100644 --- a/packages/my-queries-storage/src/query-storage.ts +++ b/packages/my-queries-storage/src/query-storage.ts @@ -8,6 +8,7 @@ interface QueryStorage { loadAll(namespace?: string): Promise[]>; updateAttributes(id: string, data: Partial>): Promise>; delete(id: string): Promise; + setOrgAndGroupId(orgId: string, groupId: string): void; } export interface RecentQueryStorage From 729c6db0b5d7a360be858437a8aa8e32649bebbf Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Thu, 17 Jul 2025 11:06:56 -0400 Subject: [PATCH 10/26] minor fixes --- packages/compass-user-data/src/index.ts | 2 +- packages/compass-user-data/src/user-data.ts | 19 ++++++++++++++++--- .../src/compass-query-storage.ts | 4 +--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/compass-user-data/src/index.ts b/packages/compass-user-data/src/index.ts index b216fd77f99..12e0cd4fdae 100644 --- a/packages/compass-user-data/src/index.ts +++ b/packages/compass-user-data/src/index.ts @@ -1,3 +1,3 @@ export type { Stats, ReadAllResult, ReadAllWithStatsResult } from './user-data'; -export { IUserData, FileUserData } from './user-data'; +export { type IUserData, FileUserData } from './user-data'; export { z } from 'zod'; diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index c183dca7006..0ca41bb65d0 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -73,7 +73,6 @@ export abstract class IUserData { protected readonly validator: T; protected readonly serialize: SerializeContent>; protected readonly deserialize: DeserializeContent; - constructor( validator: T, { @@ -96,6 +95,7 @@ export abstract class IUserData { id: string, data: Partial> ): Promise>; + abstract setOrgAndGroupId(orgId: string, groupId: string): void; } export class FileUserData extends IUserData { @@ -333,6 +333,19 @@ export class FileUserData extends IUserData { }); return await this.readOne(id); } + + setOrgAndGroupId(orgId: string, groupId: string): void { + // sample log error + log.error( + mongoLogId(1_001_000_237), // not sure what this log id should be + 'UserData', + 'setOrgAndGroupId should not be called for FileUserData', + { + orgId, + groupId, + } + ); + } } // TODO: update endpoints to reflect the merged api endpoints @@ -340,8 +353,8 @@ export class AtlasUserData extends IUserData { private readonly authenticatedFetch; // should this BASE_URL be a parameter passed to the constructor? // this might make future usage of this code easier, if we want to call a different endpoint - private readonly orgId; - private readonly groupId; + private orgId: string = ''; + private groupId: string = ''; private readonly BASE_URL = 'cluster-connection.cloud-local.mongodb.com'; constructor( validator: T, diff --git a/packages/my-queries-storage/src/compass-query-storage.ts b/packages/my-queries-storage/src/compass-query-storage.ts index 3856366cbd4..042b8a780c3 100644 --- a/packages/my-queries-storage/src/compass-query-storage.ts +++ b/packages/my-queries-storage/src/compass-query-storage.ts @@ -54,9 +54,7 @@ export abstract class CompassQueryStorage { } setOrgAndGroupId(orgId: string, groupId: string): void { - if (this.userData instanceof AtlasUserData) { - this.userData.setOrgAndGroupId(orgId, groupId); - } + this.userData.setOrgAndGroupId?.(orgId, groupId); } abstract saveQuery(data: Partial>): Promise; From 055b898dca667de441d3fd5f1aae486371e4359b Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Fri, 18 Jul 2025 16:59:39 -0400 Subject: [PATCH 11/26] unit testing --- package-lock.json | 4 +- .../src/stores/query-bar-store.ts | 5 - packages/compass-user-data/package.json | 3 +- packages/compass-user-data/src/index.ts | 2 +- .../compass-user-data/src/user-data.spec.ts | 512 ++++++++++++++---- packages/compass-user-data/src/user-data.ts | 161 +++--- .../src/compass-query-storage.ts | 4 - .../my-queries-storage/src/query-storage.ts | 1 - 8 files changed, 489 insertions(+), 203 deletions(-) diff --git a/package-lock.json b/package-lock.json index cdff91ba303..8b7b086a1b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47908,10 +47908,9 @@ }, "packages/compass-user-data": { "name": "@mongodb-js/compass-user-data", - "version": "0.7.5", + "version": "0.8.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-connections": "^1.65.0", "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", "write-file-atomic": "^5.0.1", @@ -59722,7 +59721,6 @@ "@mongodb-js/compass-user-data": { "version": "file:packages/compass-user-data", "requires": { - "@mongodb-js/compass-connections": "^1.65.0", "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", "@mongodb-js/eslint-config-compass": "^1.4.1", diff --git a/packages/compass-query-bar/src/stores/query-bar-store.ts b/packages/compass-query-bar/src/stores/query-bar-store.ts index 552045e6936..c3a05189d6b 100644 --- a/packages/compass-query-bar/src/stores/query-bar-store.ts +++ b/packages/compass-query-bar/src/stores/query-bar-store.ts @@ -131,11 +131,6 @@ export function activatePlugin( const favoriteQueryStorage = favoriteQueryStorageAccess?.getStorage(); const recentQueryStorage = recentQueryStorageAccess?.getStorage(); - const orgId = connectionInfoRef.current.atlasMetadata.orgId; - const groupId = connectionInfoRef.current.atlasMetadata.projectId; - favoriteQueryStorage.setOrgAndGroupId(orgId, groupId); - recentQueryStorage.setOrgAndGroupId(orgId, groupId); - const store = configureStore( { namespace: namespace ?? '', diff --git a/packages/compass-user-data/package.json b/packages/compass-user-data/package.json index c46990f9be3..43bd032f669 100644 --- a/packages/compass-user-data/package.json +++ b/packages/compass-user-data/package.json @@ -12,7 +12,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.7.5", + "version": "0.8.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -51,7 +51,6 @@ "dependencies": { "@mongodb-js/compass-logging": "^1.7.5", "@mongodb-js/compass-utils": "^0.9.4", - "@mongodb-js/compass-connections": "^1.65.0", "write-file-atomic": "^5.0.1", "zod": "^3.25.17" }, diff --git a/packages/compass-user-data/src/index.ts b/packages/compass-user-data/src/index.ts index 12e0cd4fdae..3db25e689f2 100644 --- a/packages/compass-user-data/src/index.ts +++ b/packages/compass-user-data/src/index.ts @@ -1,3 +1,3 @@ export type { Stats, ReadAllResult, ReadAllWithStatsResult } from './user-data'; -export { type IUserData, FileUserData } from './user-data'; +export { type IUserData, FileUserData, AtlasUserData } from './user-data'; export { z } from 'zod'; diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index f39ea917964..547d3cdfbdf 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -3,8 +3,13 @@ import { Stats } from 'fs'; import os from 'os'; import path from 'path'; import { expect } from 'chai'; -import { FileUserData, type FileUserDataOptions } from './user-data'; +import { + FileUserData, + AtlasUserData, + type FileUserDataOptions, +} from './user-data'; import { z, type ZodError } from 'zod'; +import sinon from 'sinon'; type ValidatorOptions = { allowUnknownProps?: boolean; @@ -80,7 +85,6 @@ describe('user-data', function () { ); const result = await getUserData().readAll(); - // sort result.data.sort((first, second) => first.name.localeCompare(second.name) ); @@ -278,7 +282,7 @@ describe('user-data', function () { }); }); - it('does not strip off unknown props that are unknow to validator when specified', async function () { + it('does not strip off unknown props that are unknown to validator when specified', async function () { await writeFileToStorage( 'data.json', JSON.stringify({ @@ -419,111 +423,397 @@ describe('user-data', function () { }); }); -// describe('AtlasUserData', function () { -// let AtlasUserData: any; -// let atlasServiceMock: any; -// let validator: any; -// let instance: any; - -// before(async function () { -// // Dynamically import AtlasUserData to avoid circular deps -// const module = await import('./user-data'); -// AtlasUserData = module.AtlasUserData; -// validator = getTestSchema(); -// }); - -// beforeEach(function () { -// atlasServiceMock = { -// authenticatedFetch: sinon.stub(), -// }; -// instance = new AtlasUserData(validator, atlasServiceMock, { -// groupId: 'test-group', -// projectId: 'test-project', -// endpoint: '/api/user-data', -// }); -// }); - -// it('constructs with dependencies', function () { -// expect(instance).to.have.property('atlasService', atlasServiceMock); -// expect(instance).to.have.property('groupId', 'test-group'); -// expect(instance).to.have.property('projectId', 'test-project'); -// expect(instance).to.have.property('endpoint', '/api/user-data'); -// }); - -// it('write: calls authenticatedFetch and validates response', async function () { -// const item = { name: 'Atlas', hasDarkMode: false }; -// atlasServiceMock.authenticatedFetch.resolves({ -// ok: true, -// json: async () => await Promise.resolve(item), -// }); -// const result = await instance.write('id1', item); -// expect(result).to.be.true; -// expect(atlasServiceMock.authenticatedFetch.calledOnce).to.be.true; -// }); - -// it('write: handles API error', async function () { -// atlasServiceMock.authenticatedFetch.resolves({ ok: false, status: 500 }); -// const result = await instance.write('id1', { name: 'Atlas' }); -// expect(result).to.be.false; -// }); - -// it('delete: calls authenticatedFetch and returns true on success', async function () { -// atlasServiceMock.authenticatedFetch.resolves({ ok: true }); -// const result = await instance.delete('id1'); -// expect(result).to.be.true; -// }); - -// it('delete: returns false on API failure', async function () { -// atlasServiceMock.authenticatedFetch.resolves({ ok: false }); -// const result = await instance.delete('id1'); -// expect(result).to.be.false; -// }); - -// it('readAll: returns validated items from API', async function () { -// const items = [ -// { name: 'Atlas', hasDarkMode: true }, -// { name: 'Compass', hasDarkMode: false }, -// ]; -// atlasServiceMock.authenticatedFetch.resolves({ -// ok: true, -// json: async () => await Promise.resolve(items), -// }); -// const result = await instance.readAll(); -// expect(result.data).to.have.lengthOf(2); -// expect(result.errors).to.have.lengthOf(0); -// expect(result.data[0]).to.have.property('name'); -// }); - -// it('readAll: returns errors for invalid items', async function () { -// const items = [ -// { name: 'Atlas', hasDarkMode: 'not-a-bool' }, -// { name: 'Compass', hasDarkMode: false }, -// ]; -// atlasServiceMock.authenticatedFetch.resolves({ -// ok: true, -// json: async () => await Promise.resolve(items), -// }); -// const result = await instance.readAll(); -// expect(result.data).to.have.lengthOf(1); -// expect(result.errors).to.have.lengthOf(1); -// }); - -// it('updateAttributes: calls authenticatedFetch and validates response', async function () { -// const attrs = { hasDarkMode: false }; -// atlasServiceMock.authenticatedFetch.resolves({ -// ok: true, -// json: async () => -// await Promise.resolve({ name: 'Atlas', hasDarkMode: false }), -// }); -// const result = await instance.updateAttributes('id1', attrs); -// expect(result).to.deep.equal({ name: 'Atlas', hasDarkMode: false }); -// }); - -// it('updateAttributes: returns undefined on API error', async function () { -// atlasServiceMock.authenticatedFetch.resolves({ ok: false }); -// const result = await instance.updateAttributes('id1', { -// hasDarkMode: true, -// }); -// expect(result).to.be.undefined; -// }); -// }); +describe('AtlasUserData', function () { + let sandbox: sinon.SinonSandbox; + let authenticatedFetchStub: sinon.SinonStub; + + beforeEach(function () { + sandbox = sinon.createSandbox(); + authenticatedFetchStub = sandbox.stub(); + }); + + afterEach(function () { + sandbox.restore(); + }); + + const getAtlasUserData = ( + validatorOpts: ValidatorOptions = {}, + orgId = 'test-org', + groupId = 'test-group', + type = 'favorites' + ) => { + return new AtlasUserData( + getTestSchema(validatorOpts), + authenticatedFetchStub, + orgId, + groupId, + type, + {} + ); + }; + + const mockResponse = (data: unknown, ok = true, status = 200) => { + return { + ok, + status, + statusText: status === 200 ? 'OK' : 'Error', + json: () => Promise.resolve(data), + }; + }; + + context('AtlasUserData.write', function () { + it('writes data successfully', async function () { + authenticatedFetchStub.resolves(mockResponse({})); + + const userData = getAtlasUserData(); + const result = await userData.write('test-id', { name: 'VSCode' }); + + expect(result).to.be.true; + expect(authenticatedFetchStub).to.have.been.calledOnce; + + const [url, options] = authenticatedFetchStub.firstCall.args; + expect(url).to.equal( + 'cluster-connection.cloud-local.mongodb.com/favorites/test-org/test-group' + ); + expect(options.method).to.equal('POST'); + expect(options.headers['Content-Type']).to.equal('application/json'); + + const body = JSON.parse(options.body as string); + expect(body.id).to.equal('test-id'); + expect(body.groupId).to.equal('test-group'); + expect(body.data).to.be.a('string'); + expect(JSON.parse(body.data as string)).to.deep.equal({ name: 'VSCode' }); + expect(body.createdAt).to.be.a('string'); + expect(new Date(body.createdAt as string)).to.be.instanceOf(Date); + }); + + it('returns false when response is not ok', async function () { + authenticatedFetchStub.resolves(mockResponse({}, false, 500)); + + const userData = getAtlasUserData(); + + const result = await userData.write('test-id', { name: 'VSCode' }); + expect(result).to.be.false; + }); + + it('validator removes unknown props', async function () { + authenticatedFetchStub.resolves(mockResponse({})); + + const userData = getAtlasUserData(); + + const result = await userData.write('test-id', { + name: 'VSCode', + randomProp: 'should fail', + }); + + expect(result).to.be.true; + }); + + it('uses custom serializer when provided', async function () { + authenticatedFetchStub.resolves(mockResponse({})); + + const userData = new AtlasUserData( + getTestSchema(), + authenticatedFetchStub, + 'test-org', + 'test-group', + 'favorites', + { + serialize: (data) => `custom:${JSON.stringify(data)}`, + } + ); + + await userData.write('test-id', { name: 'Custom' }); + + const [, options] = authenticatedFetchStub.firstCall.args; + const body = JSON.parse(options.body as string); + expect(body.data).to.equal('custom:{"name":"Custom"}'); + }); + }); + + context('AtlasUserData.delete', function () { + it('deletes data successfully', async function () { + authenticatedFetchStub.resolves(mockResponse({})); + + const userData = getAtlasUserData(); + const result = await userData.delete('test-id'); + + expect(result).to.be.true; + expect(authenticatedFetchStub).to.have.been.calledOnce; + + const [url, options] = authenticatedFetchStub.firstCall.args; + expect(url).to.equal( + 'cluster-connection.cloud-local.mongodb.com/favorites/test-org/test-group/test-id' + ); + expect(options.method).to.equal('DELETE'); + }); + + it('returns false when response is not ok', async function () { + authenticatedFetchStub.resolves(mockResponse({}, false, 404)); + + const userData = getAtlasUserData(); + + const result = await userData.delete('test-id'); + expect(result).to.be.false; + }); + }); + + context('AtlasUserData.readAll', function () { + it('reads all data successfully with defaults', async function () { + const responseData = [ + { data: JSON.stringify({ name: 'VSCode' }) }, + { data: JSON.stringify({ name: 'Mongosh' }) }, + ]; + authenticatedFetchStub.resolves(mockResponse(responseData)); + + const userData = getAtlasUserData(); + const result = await userData.readAll(); + + expect(result.data).to.have.lengthOf(2); + expect(result.errors).to.have.lengthOf(0); + + // Sort for consistent testing + result.data.sort((first, second) => + first.name.localeCompare(second.name) + ); + + expect(result.data).to.deep.equal([ + { + ...defaultValues(), + name: 'Mongosh', + }, + { + ...defaultValues(), + name: 'VSCode', + }, + ]); + + expect(authenticatedFetchStub).to.have.been.calledOnce; + const [url, options] = authenticatedFetchStub.firstCall.args; + expect(url).to.equal( + 'cluster-connection.cloud-local.mongodb.com/favorites/test-org/test-group' + ); + expect(options.method).to.equal('GET'); + }); + + it('handles empty response', async function () { + authenticatedFetchStub.resolves(mockResponse([])); + + const userData = getAtlasUserData(); + const result = await userData.readAll(); + + expect(result.data).to.have.lengthOf(0); + expect(result.errors).to.have.lengthOf(0); + }); + + it('handles non-array response', async function () { + authenticatedFetchStub.resolves(mockResponse({ notAnArray: true })); + + const userData = getAtlasUserData(); + const result = await userData.readAll(); + + expect(result.data).to.have.lengthOf(0); + expect(result.errors).to.have.lengthOf(0); + }); + + it('handles errors gracefully', async function () { + authenticatedFetchStub.rejects(new Error('Unknown error')); + + const userData = getAtlasUserData(); + const result = await userData.readAll(); + + expect(result.data).to.have.lengthOf(0); + expect(result.errors).to.have.lengthOf(1); + expect(result.errors[0].message).to.equal('Unknown error'); + }); + + it('handles non-ok response gracefully', async function () { + authenticatedFetchStub.resolves(mockResponse({}, false, 500)); + + const userData = getAtlasUserData(); + const result = await userData.readAll(); + + expect(result.data).to.have.lengthOf(0); + expect(result.errors).to.have.lengthOf(1); + expect(result.errors[0].message).to.contain('Failed to get data: 500'); + }); + + it('uses custom deserializer when provided', async function () { + const responseData = [{ data: 'custom:{"name":"Custom"}' }]; + authenticatedFetchStub.resolves(mockResponse(responseData)); + + const userData = new AtlasUserData( + getTestSchema(), + authenticatedFetchStub, + 'test-org', + 'test-group', + 'favorites', + { + deserialize: (data) => { + if (data.startsWith('custom:')) { + return JSON.parse(data.slice(7)); + } + return JSON.parse(data); + }, + } + ); + + const result = await userData.readAll(); + + expect(result.data).to.have.lengthOf(1); + expect(result.data[0]).to.deep.equal({ + ...defaultValues(), + name: 'Custom', + }); + expect(result.errors).to.have.lengthOf(0); + }); + + it('strips unknown props by default', async function () { + const responseData = [ + { + data: JSON.stringify({ + name: 'VSCode', + unknownProp: 'should be stripped', + }), + }, + ]; + authenticatedFetchStub.resolves(mockResponse(responseData)); + + const userData = getAtlasUserData(); + const result = await userData.readAll(); + + expect(result.data).to.have.lengthOf(1); + expect(result.data[0]).to.deep.equal({ + ...defaultValues(), + name: 'VSCode', + }); + expect(result.data[0]).to.not.have.property('unknownProp'); + expect(result.errors).to.have.lengthOf(0); + }); + }); + + context('AtlasUserData.updateAttributes', function () { + it('updates data successfully', async function () { + const putResponse = { name: 'Updated Name', hasDarkMode: false }; + authenticatedFetchStub.resolves(mockResponse(putResponse)); + + const userData = getAtlasUserData(); + const result = await userData.updateAttributes('test-id', { + name: 'Updated Name', + hasDarkMode: false, + }); + + expect(result).to.deep.equal({ + ...defaultValues(), + name: 'Updated Name', + hasDarkMode: false, + }); + + expect(authenticatedFetchStub).to.have.been.calledOnce; + const [url, options] = authenticatedFetchStub.firstCall.args; + expect(url).to.equal( + 'cluster-connection.cloud-local.mongodb.com/favorites/test-org/test-group/test-id' + ); + expect(options.method).to.equal('PUT'); + expect(options.headers['Content-Type']).to.equal('application/json'); + }); + + it('throws error when response is not ok', async function () { + authenticatedFetchStub.resolves(mockResponse({}, false, 400)); + + const userData = getAtlasUserData(); + + try { + await userData.updateAttributes('test-id', { name: 'Updated' }); + expect.fail('Should have thrown error'); + } catch (error) { + expect(error).to.be.instanceOf(Error); + expect((error as Error).message).to.contain('Failed to update data'); + } + }); + + it('uses custom serializer for request body', async function () { + const putResponse = { name: 'Updated' }; + authenticatedFetchStub.resolves(mockResponse(putResponse)); + + const userData = new AtlasUserData( + getTestSchema(), + authenticatedFetchStub, + 'test-org', + 'test-group', + 'favorites', + { + serialize: (data) => `custom:${JSON.stringify(data)}`, + } + ); + + await userData.updateAttributes('test-id', { name: 'Updated' }); + + const [, options] = authenticatedFetchStub.firstCall.args; + expect(options.body as string).to.equal('custom:{"name":"Updated"}'); + }); + }); + + context('AtlasUserData urls', function () { + it('constructs URL correctly for write operation', async function () { + authenticatedFetchStub.resolves(mockResponse({})); + + const userData = getAtlasUserData({}, 'custom-org', 'custom-group'); + await userData.write('test-id', { name: 'Test' }); + + const [url] = authenticatedFetchStub.firstCall.args; + expect(url).to.equal( + 'cluster-connection.cloud-local.mongodb.com/favorites/custom-org/custom-group' + ); + }); + + it('constructs URL correctly for delete operation', async function () { + authenticatedFetchStub.resolves(mockResponse({})); + + const userData = getAtlasUserData({}, 'org123', 'group456'); + await userData.delete('item789'); + + const [url] = authenticatedFetchStub.firstCall.args; + expect(url).to.equal( + 'cluster-connection.cloud-local.mongodb.com/favorites/org123/group456/item789' + ); + }); + + it('constructs URL correctly for read operation', async function () { + authenticatedFetchStub.resolves(mockResponse({})); + + const userData = getAtlasUserData({}, 'org456', 'group123'); + await userData.readAll(); + + const [url] = authenticatedFetchStub.firstCall.args; + expect(url).to.equal( + 'cluster-connection.cloud-local.mongodb.com/favorites/org456/group123' + ); + }); + + it('constructs URL correctly for update operation', async function () { + const putResponse = { data: { name: 'Updated' } }; + authenticatedFetchStub.resolves(mockResponse(putResponse)); + + const userData = getAtlasUserData({}, 'org123', 'group456'); + await userData.updateAttributes('item789', { name: 'Updated' }); + + const [url] = authenticatedFetchStub.firstCall.args; + expect(url).to.equal( + 'cluster-connection.cloud-local.mongodb.com/favorites/org123/group456/item789' + ); + }); + + it('constructrs URL correctly for different types', async function () { + authenticatedFetchStub.resolves(mockResponse({})); + + const userData = getAtlasUserData({}, 'org123', 'group456', 'recent'); + await userData.write('item789', { name: 'Recent Item' }); + + const [url] = authenticatedFetchStub.firstCall.args; + expect(url).to.equal( + 'cluster-connection.cloud-local.mongodb.com/recent/org123/group456' + ); + }); + }); +}); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 0ca41bb65d0..5ea02f3d2ee 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -5,7 +5,6 @@ import { getStoragePath } from '@mongodb-js/compass-utils'; import type { z } from 'zod'; import writeFile from 'write-file-atomic'; import { Semaphore } from './semaphore'; -// import { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; const { log, mongoLogId } = createLogger('COMPASS-USER-STORAGE'); @@ -95,7 +94,6 @@ export abstract class IUserData { id: string, data: Partial> ): Promise>; - abstract setOrgAndGroupId(orgId: string, groupId: string): void; } export class FileUserData extends IUserData { @@ -333,28 +331,14 @@ export class FileUserData extends IUserData { }); return await this.readOne(id); } - - setOrgAndGroupId(orgId: string, groupId: string): void { - // sample log error - log.error( - mongoLogId(1_001_000_237), // not sure what this log id should be - 'UserData', - 'setOrgAndGroupId should not be called for FileUserData', - { - orgId, - groupId, - } - ); - } } -// TODO: update endpoints to reflect the merged api endpoints +// TODO: update endpoints to reflect the merged api endpoints https://jira.mongodb.org/browse/CLOUDP-329716 export class AtlasUserData extends IUserData { private readonly authenticatedFetch; - // should this BASE_URL be a parameter passed to the constructor? - // this might make future usage of this code easier, if we want to call a different endpoint private orgId: string = ''; private groupId: string = ''; + private readonly type: string; private readonly BASE_URL = 'cluster-connection.cloud-local.mongodb.com'; constructor( validator: T, @@ -362,58 +346,86 @@ export class AtlasUserData extends IUserData { url: RequestInfo | URL, options?: RequestInit ) => Promise, + orgId: string, + groupId: string, + type: string, { serialize, deserialize }: AtlasUserDataOptions> ) { super(validator, { serialize, deserialize }); this.authenticatedFetch = authenticatedFetch; + this.orgId = orgId; + this.groupId = groupId; + this.type = type; } async write(id: string, content: z.input): Promise { - this.validator.parse(content); + try { + this.validator.parse(content); - // do not need to use id because content already contains the id - const response = await this.authenticatedFetch(this.getUrl(), { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - id: id, - data: this.serialize(content), - createdAt: new Date(), - groupId: this.groupId, - }), - }); - // TODO: fix this error handling, should fit current compass needs - if (!response.ok) { - throw new Error( - `Failed to post data: ${response.status} ${response.statusText}` + const response = await this.authenticatedFetch(this.getUrl(), { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + id: id, + data: this.serialize(content), + createdAt: new Date(), + groupId: this.groupId, + }), + }); + + if (!response.ok) { + throw new Error( + `Failed to post data: ${response.status} ${response.statusText}` + ); + } + + return true; + } catch (error) { + log.error( + mongoLogId(1_001_000_362), + 'Atlas Backend', + 'Error writing data', + { + url: this.getUrl(), + error: (error as Error).message, + } ); + return false; } - return true; } async delete(id: string): Promise { - const response = await this.authenticatedFetch(this.getUrl() + `/${id}`, { - method: 'DELETE', - }); - if (!response.ok) { - throw new Error( - `Failed to delete data: ${response.status} ${response.statusText}` + try { + const response = await this.authenticatedFetch(this.getUrl() + `/${id}`, { + method: 'DELETE', + }); + if (!response.ok) { + throw new Error( + `Failed to delete data: ${response.status} ${response.statusText}` + ); + } + return true; + } catch (error) { + log.error( + mongoLogId(1_001_000_363), + 'Atlas Backend', + 'Error deleting data', + { + url: this.getUrl(), + error: (error as Error).message, + } ); + return false; } - return true; } async readAll(): Promise> { try { const response = await this.authenticatedFetch(this.getUrl(), { method: 'GET', - headers: { - accept: 'application/json', - }, }); - // TODO: fix this error handling, should fit current compass needs if (!response.ok) { throw new Error( `Failed to get data: ${response.status} ${response.statusText}` @@ -435,38 +447,35 @@ export class AtlasUserData extends IUserData { id: string, data: Partial> ): Promise> { - const response = await this.authenticatedFetch(this.getUrl() + `/${id}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - // TODO: not sure whether currently compass sometimes adds to data or always replaces it - // figure out if we should get all data, find specific query by id, then update using JS - body: this.serialize(data), - }); - if (!response.ok) { - throw new Error( - `Failed to update data: ${response.status} ${response.statusText}` + try { + const response = await this.authenticatedFetch(this.getUrl() + `/${id}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: this.serialize(data), + }); + if (!response.ok) { + throw new Error( + `Failed to update data: ${response.status} ${response.statusText}` + ); + } + return this.validator.parse(data); + } catch (error) { + log.error( + mongoLogId(1_001_000_364), + 'Atlas Backend', + 'Error updating data', + { + url: this.getUrl(), + error: (error as Error).message, + } ); + throw new Error('Failed to update data'); } - const json = await response.json(); - // TODO: fix this, currently endpoint does not return the updated data - // so we need to decide whether this is necessary - return this.validator.parse(json.data); - } - - setOrgAndGroupId(orgId: string, groupId: string): void { - this.orgId = orgId; - this.groupId = groupId; } private getUrl() { - // if (endpoint.startsWith('/')) { - // endpoint = endpoint.slice(1); - // } - // if (endpoint.endsWith('/')) { - // endpoint = endpoint.slice(0, -1); - // } - return `${this.BASE_URL}/queries/favorites/${this.orgId}/${this.groupId}`; + return `${this.BASE_URL}/${this.type}/${this.orgId}/${this.groupId}`; } } diff --git a/packages/my-queries-storage/src/compass-query-storage.ts b/packages/my-queries-storage/src/compass-query-storage.ts index 042b8a780c3..c133ee81c53 100644 --- a/packages/my-queries-storage/src/compass-query-storage.ts +++ b/packages/my-queries-storage/src/compass-query-storage.ts @@ -53,10 +53,6 @@ export abstract class CompassQueryStorage { return await this.userData.updateAttributes(id, data); } - setOrgAndGroupId(orgId: string, groupId: string): void { - this.userData.setOrgAndGroupId?.(orgId, groupId); - } - abstract saveQuery(data: Partial>): Promise; } diff --git a/packages/my-queries-storage/src/query-storage.ts b/packages/my-queries-storage/src/query-storage.ts index 7d15994453e..a932e0a46d5 100644 --- a/packages/my-queries-storage/src/query-storage.ts +++ b/packages/my-queries-storage/src/query-storage.ts @@ -8,7 +8,6 @@ interface QueryStorage { loadAll(namespace?: string): Promise[]>; updateAttributes(id: string, data: Partial>): Promise>; delete(id: string): Promise; - setOrgAndGroupId(orgId: string, groupId: string): void; } export interface RecentQueryStorage From 2058a32dc0f1c26ea661adcf8f7d0857130f4a25 Mon Sep 17 00:00:00 2001 From: Moses Yang Date: Fri, 18 Jul 2025 17:25:27 -0400 Subject: [PATCH 12/26] typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- packages/compass-user-data/src/user-data.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index 547d3cdfbdf..f586a87f0a9 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -804,7 +804,7 @@ describe('AtlasUserData', function () { ); }); - it('constructrs URL correctly for different types', async function () { + it('constructs URL correctly for different types', async function () { authenticatedFetchStub.resolves(mockResponse({})); const userData = getAtlasUserData({}, 'org123', 'group456', 'recent'); From 296147a7791b1e750000016e2a6b5eaea8ac0ab3 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Fri, 18 Jul 2025 17:26:08 -0400 Subject: [PATCH 13/26] package-lock.json --- package-lock.json | 458 ---------------------------------------------- 1 file changed, 458 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac489fbd37b..b4033e32ad2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43688,18 +43688,6 @@ "typescript": "^5.8.3" } }, - "packages/atlas-service/node_modules/@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "license": "SSPL", - "dependencies": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, "packages/atlas-service/node_modules/@mongodb-js/devtools-connect": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.9.2.tgz", @@ -43733,18 +43721,6 @@ "node": ">=0.3.1" } }, - "packages/atlas-service/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "packages/atlas-service/node_modules/sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -43763,28 +43739,6 @@ "url": "https://opencollective.com/sinon" } }, - "packages/atlas-service/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/atlas-service/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "packages/bson-transpilers": { "version": "3.2.14", "license": "SSPL", @@ -45189,18 +45143,6 @@ "xvfb-maybe": "^0.2.1" } }, - "packages/compass-data-modeling/node_modules/@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "license": "SSPL", - "dependencies": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, "packages/compass-data-modeling/node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -45271,18 +45213,6 @@ "dev": true, "license": "MIT" }, - "packages/compass-data-modeling/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "packages/compass-data-modeling/node_modules/sinon": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", @@ -45302,28 +45232,6 @@ "url": "https://opencollective.com/sinon" } }, - "packages/compass-data-modeling/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/compass-data-modeling/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "packages/compass-database": { "name": "@mongodb-js/compass-database", "version": "3.19.1", @@ -47010,30 +46918,6 @@ "sinon": "^9.2.3" } }, - "packages/compass-preferences-model/node_modules/@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "license": "SSPL", - "dependencies": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, - "packages/compass-preferences-model/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "packages/compass-preferences-model/node_modules/sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -47061,19 +46945,6 @@ "node": ">=0.3.1" } }, - "packages/compass-preferences-model/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "packages/compass-preferences-model/node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", @@ -47082,15 +46953,6 @@ "node": ">=12" } }, - "packages/compass-preferences-model/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "packages/compass-query-bar": { "name": "@mongodb-js/compass-query-bar", "version": "8.67.0", @@ -47629,52 +47491,6 @@ "typescript": "^5.8.3" } }, - "packages/compass-shell/node_modules/@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "license": "SSPL", - "dependencies": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, - "packages/compass-shell/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/compass-shell/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/compass-shell/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "packages/compass-sidebar": { "name": "@mongodb-js/compass-sidebar", "version": "5.66.0", @@ -49040,18 +48856,6 @@ "typescript": "^5.8.3" } }, - "packages/connection-storage/node_modules/@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "license": "SSPL", - "dependencies": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, "packages/connection-storage/node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -49061,18 +48865,6 @@ "node": ">=0.3.1" } }, - "packages/connection-storage/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "packages/connection-storage/node_modules/sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -49091,28 +48883,6 @@ "url": "https://opencollective.com/sinon" } }, - "packages/connection-storage/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/connection-storage/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "packages/data-service": { "name": "mongodb-data-service", "version": "22.29.1", @@ -50729,18 +50499,6 @@ "typescript": "^5.8.3" } }, - "packages/my-queries-storage/node_modules/@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "license": "SSPL", - "dependencies": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, "packages/my-queries-storage/node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -50750,18 +50508,6 @@ "node": ">=0.3.1" } }, - "packages/my-queries-storage/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "packages/my-queries-storage/node_modules/sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -50781,28 +50527,6 @@ "url": "https://opencollective.com/sinon" } }, - "packages/my-queries-storage/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/my-queries-storage/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "packages/notary-service-client": { "name": "@mongodb-js/mongodb-notary-service-client", "version": "2.0.4", @@ -56716,17 +56440,6 @@ "typescript": "^5.8.3" }, "dependencies": { - "@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "requires": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, "@mongodb-js/devtools-connect": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.9.2.tgz", @@ -56749,11 +56462,6 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, "sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -56767,20 +56475,6 @@ "nise": "^4.0.4", "supports-color": "^7.1.0" } - }, - "write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - } - }, - "zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, @@ -57840,17 +57534,6 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "requires": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, "@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -57913,11 +57596,6 @@ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "dev": true }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, "sinon": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", @@ -57931,20 +57609,6 @@ "nise": "^5.1.5", "supports-color": "^7.2.0" } - }, - "write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - } - }, - "zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, @@ -59589,38 +59253,6 @@ "redux": "^4.2.1", "redux-thunk": "^2.4.2", "typescript": "^5.8.3" - }, - "dependencies": { - "@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "requires": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, - "write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - } - }, - "zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" - } } }, "@mongodb-js/compass-sidebar": { @@ -60683,28 +60315,12 @@ "typescript": "^5.8.3" }, "dependencies": { - "@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "requires": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, "sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -60718,20 +60334,6 @@ "nise": "^4.0.4", "supports-color": "^7.1.0" } - }, - "write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - } - }, - "zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, @@ -61473,28 +61075,12 @@ "typescript": "^5.8.3" }, "dependencies": { - "@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "requires": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, "sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -61508,20 +61094,6 @@ "nise": "^4.0.4", "supports-color": "^7.1.0" } - }, - "write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - } - }, - "zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, @@ -69807,22 +69379,6 @@ "yargs-parser": "^21.1.1" }, "dependencies": { - "@mongodb-js/compass-user-data": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/compass-user-data/-/compass-user-data-0.8.0.tgz", - "integrity": "sha512-txD49s7nGqsR8Vw69gkF2H51tOrsCoxyMLGSNTiczbfRqYYDyK2O2WcbQvr8BnGNEk0d7rI3mBW7y60S5ljfIg==", - "requires": { - "@mongodb-js/compass-logging": "^1.7.6", - "@mongodb-js/compass-utils": "^0.9.5", - "write-file-atomic": "^5.0.1", - "zod": "^3.25.17" - } - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, "sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -69845,24 +69401,10 @@ } } }, - "write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - } - }, "yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" - }, - "zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, From 18240da6c86644da55b57b846f81f4dafdbfd911 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Mon, 21 Jul 2025 15:37:45 -0400 Subject: [PATCH 14/26] fix: parse one by one in readAll --- packages/compass-user-data/src/user-data.ts | 49 ++++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 5ea02f3d2ee..6d034ae94e9 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -422,25 +422,40 @@ export class AtlasUserData extends IUserData { } async readAll(): Promise> { - try { - const response = await this.authenticatedFetch(this.getUrl(), { - method: 'GET', - }); - if (!response.ok) { - throw new Error( + const response = await this.authenticatedFetch(this.getUrl(), { + method: 'GET', + }); + const result: ReadAllResult = { + data: [], + errors: [], + }; + if (!response.ok) { + log.error( + mongoLogId(1_001_000_364), + 'Atlas Backend', + 'Error reading data', + { + url: this.getUrl(), + error: `Status ${response.status} ${response.statusText}`, + } + ); + result.errors.push( + new Error( `Failed to get data: ${response.status} ${response.statusText}` - ); + ) + ); + return result; + } + const json = await response.json(); + for (const item of json) { + try { + const parsedData = this.deserialize(item.data as string); + result.data.push(this.validator.parse(parsedData) as z.output); + } catch (error) { + result.errors.push(error as Error); } - const json = await response.json(); - const data = Array.isArray(json) - ? json.map((item) => - this.validator.parse(this.deserialize(item.data as string)) - ) - : []; - return { data, errors: [] }; - } catch (error) { - return { data: [], errors: [error as Error] }; } + return result; } async updateAttributes( @@ -463,7 +478,7 @@ export class AtlasUserData extends IUserData { return this.validator.parse(data); } catch (error) { log.error( - mongoLogId(1_001_000_364), + mongoLogId(1_001_000_365), 'Atlas Backend', 'Error updating data', { From 31a864380878ecfff6d3a63225fa45915d041046 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Mon, 21 Jul 2025 16:06:33 -0400 Subject: [PATCH 15/26] fix: change updateAttributes return type to boolean --- packages/compass-user-data/src/user-data.ts | 24 +++++++++++-------- .../src/compass-query-storage.ts | 2 +- .../my-queries-storage/src/query-storage.ts | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 6d034ae94e9..6f706c7c3e6 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -93,7 +93,7 @@ export abstract class IUserData { abstract updateAttributes( id: string, data: Partial> - ): Promise>; + ): Promise; } export class FileUserData extends IUserData { @@ -324,12 +324,16 @@ export class FileUserData extends IUserData { async updateAttributes( id: string, data: Partial> - ): Promise> { - await this.write(id, { - ...((await this.readOne(id)) ?? {}), - ...data, - }); - return await this.readOne(id); + ): Promise { + try { + await this.write(id, { + ...((await this.readOne(id)) ?? {}), + ...data, + }); + return true; + } catch { + return false; + } } } @@ -461,7 +465,7 @@ export class AtlasUserData extends IUserData { async updateAttributes( id: string, data: Partial> - ): Promise> { + ): Promise { try { const response = await this.authenticatedFetch(this.getUrl() + `/${id}`, { method: 'PUT', @@ -475,7 +479,7 @@ export class AtlasUserData extends IUserData { `Failed to update data: ${response.status} ${response.statusText}` ); } - return this.validator.parse(data); + return true; } catch (error) { log.error( mongoLogId(1_001_000_365), @@ -486,7 +490,7 @@ export class AtlasUserData extends IUserData { error: (error as Error).message, } ); - throw new Error('Failed to update data'); + return false; } } diff --git a/packages/my-queries-storage/src/compass-query-storage.ts b/packages/my-queries-storage/src/compass-query-storage.ts index c133ee81c53..288e84e41be 100644 --- a/packages/my-queries-storage/src/compass-query-storage.ts +++ b/packages/my-queries-storage/src/compass-query-storage.ts @@ -49,7 +49,7 @@ export abstract class CompassQueryStorage { async updateAttributes( id: string, data: Partial> - ): Promise> { + ): Promise { return await this.userData.updateAttributes(id, data); } diff --git a/packages/my-queries-storage/src/query-storage.ts b/packages/my-queries-storage/src/query-storage.ts index a932e0a46d5..9ee445a646c 100644 --- a/packages/my-queries-storage/src/query-storage.ts +++ b/packages/my-queries-storage/src/query-storage.ts @@ -6,7 +6,7 @@ import type { interface QueryStorage { loadAll(namespace?: string): Promise[]>; - updateAttributes(id: string, data: Partial>): Promise>; + updateAttributes(id: string, data: Partial>): Promise; delete(id: string): Promise; } From e88856f1d51e7ff738cf2230589a97cbb1e7f659 Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Tue, 22 Jul 2025 10:05:28 -0400 Subject: [PATCH 16/26] stricter typing for type param and fix update tests --- .../compass-user-data/src/user-data.spec.ts | 27 ++++------ packages/compass-user-data/src/user-data.ts | 53 ++++++++----------- 2 files changed, 33 insertions(+), 47 deletions(-) diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index f586a87f0a9..3669630767a 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -440,7 +440,7 @@ describe('AtlasUserData', function () { validatorOpts: ValidatorOptions = {}, orgId = 'test-org', groupId = 'test-group', - type = 'favorites' + type: 'favorites' | 'recents' | 'pipelines' = 'favorites' ) => { return new AtlasUserData( getTestSchema(validatorOpts), @@ -613,7 +613,7 @@ describe('AtlasUserData', function () { const result = await userData.readAll(); expect(result.data).to.have.lengthOf(0); - expect(result.errors).to.have.lengthOf(0); + expect(result.errors).to.have.lengthOf(1); }); it('handles errors gracefully', async function () { @@ -703,11 +703,7 @@ describe('AtlasUserData', function () { hasDarkMode: false, }); - expect(result).to.deep.equal({ - ...defaultValues(), - name: 'Updated Name', - hasDarkMode: false, - }); + expect(result).equals(true); expect(authenticatedFetchStub).to.have.been.calledOnce; const [url, options] = authenticatedFetchStub.firstCall.args; @@ -718,18 +714,15 @@ describe('AtlasUserData', function () { expect(options.headers['Content-Type']).to.equal('application/json'); }); - it('throws error when response is not ok', async function () { + it('returns false when response is not ok', async function () { authenticatedFetchStub.resolves(mockResponse({}, false, 400)); const userData = getAtlasUserData(); - try { - await userData.updateAttributes('test-id', { name: 'Updated' }); - expect.fail('Should have thrown error'); - } catch (error) { - expect(error).to.be.instanceOf(Error); - expect((error as Error).message).to.contain('Failed to update data'); - } + const result = await userData.updateAttributes('test-id', { + name: 'Updated', + }); + expect(result).equals(false); }); it('uses custom serializer for request body', async function () { @@ -807,12 +800,12 @@ describe('AtlasUserData', function () { it('constructs URL correctly for different types', async function () { authenticatedFetchStub.resolves(mockResponse({})); - const userData = getAtlasUserData({}, 'org123', 'group456', 'recent'); + const userData = getAtlasUserData({}, 'org123', 'group456', 'recents'); await userData.write('item789', { name: 'Recent Item' }); const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/recent/org123/group456' + 'cluster-connection.cloud-local.mongodb.com/recents/org123/group456' ); }); }); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 6f706c7c3e6..e7bed19255b 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -342,7 +342,7 @@ export class AtlasUserData extends IUserData { private readonly authenticatedFetch; private orgId: string = ''; private groupId: string = ''; - private readonly type: string; + private readonly type: 'recents' | 'favorites' | 'pipelines'; private readonly BASE_URL = 'cluster-connection.cloud-local.mongodb.com'; constructor( validator: T, @@ -352,7 +352,7 @@ export class AtlasUserData extends IUserData { ) => Promise, orgId: string, groupId: string, - type: string, + type: 'recents' | 'favorites' | 'pipelines', { serialize, deserialize }: AtlasUserDataOptions> ) { super(validator, { serialize, deserialize }); @@ -426,40 +426,33 @@ export class AtlasUserData extends IUserData { } async readAll(): Promise> { - const response = await this.authenticatedFetch(this.getUrl(), { - method: 'GET', - }); const result: ReadAllResult = { data: [], errors: [], }; - if (!response.ok) { - log.error( - mongoLogId(1_001_000_364), - 'Atlas Backend', - 'Error reading data', - { - url: this.getUrl(), - error: `Status ${response.status} ${response.statusText}`, - } - ); - result.errors.push( - new Error( + try { + const response = await this.authenticatedFetch(this.getUrl(), { + method: 'GET', + }); + if (!response.ok) { + throw new Error( `Failed to get data: ${response.status} ${response.statusText}` - ) - ); - return result; - } - const json = await response.json(); - for (const item of json) { - try { - const parsedData = this.deserialize(item.data as string); - result.data.push(this.validator.parse(parsedData) as z.output); - } catch (error) { - result.errors.push(error as Error); + ); + } + const json = await response.json(); + for (const item of json) { + try { + const parsedData = this.deserialize(item.data as string); + result.data.push(this.validator.parse(parsedData) as z.output); + } catch (error) { + result.errors.push(error as Error); + } } + return result; + } catch (error) { + result.errors.push(error as Error); + return result; } - return result; } async updateAttributes( @@ -482,7 +475,7 @@ export class AtlasUserData extends IUserData { return true; } catch (error) { log.error( - mongoLogId(1_001_000_365), + mongoLogId(1_001_000_364), 'Atlas Backend', 'Error updating data', { From 3b8fc66e504044c0c3c6339c9bb0bfcb7d8b9f1d Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Tue, 22 Jul 2025 12:16:35 -0400 Subject: [PATCH 17/26] add getResourceUrl and change groupId to projectId --- packages/atlas-service/src/atlas-service.ts | 2 +- packages/atlas-service/src/util.ts | 18 +-- .../compass-user-data/src/user-data.spec.ts | 136 ++++++++++++++---- packages/compass-user-data/src/user-data.ts | 105 +++++++++----- 4 files changed, 183 insertions(+), 78 deletions(-) diff --git a/packages/atlas-service/src/atlas-service.ts b/packages/atlas-service/src/atlas-service.ts index c7e5bbd7203..8a90283693e 100644 --- a/packages/atlas-service/src/atlas-service.ts +++ b/packages/atlas-service/src/atlas-service.ts @@ -76,7 +76,7 @@ export class AtlasService { return this.cloudEndpoint(path); } driverProxyEndpoint(path?: string): string { - return `${this.config.wsBaseUrl}${normalizePath(path)}`; + return `${this.config.ccsBaseUrl}${normalizePath(path)}`; } async fetch(url: RequestInfo | URL, init?: RequestInit): Promise { throwIfNetworkTrafficDisabled(this.preferences); diff --git a/packages/atlas-service/src/util.ts b/packages/atlas-service/src/util.ts index 48abca07cd4..ef17a3e10ef 100644 --- a/packages/atlas-service/src/util.ts +++ b/packages/atlas-service/src/util.ts @@ -96,7 +96,7 @@ export type AtlasServiceConfig = { /** * MongoDB Driver WebSocket proxy base url */ - wsBaseUrl: string; + ccsBaseUrl: string; /** * Cloud UI backend base url */ @@ -131,7 +131,7 @@ export type AtlasServiceConfig = { */ const config = { 'atlas-local': { - wsBaseUrl: 'ws://localhost:61001/ws', + ccsBaseUrl: 'ws://localhost:61001/ws', cloudBaseUrl: '', atlasApiBaseUrl: 'http://localhost:8080/api/private', atlasLogin: { @@ -141,7 +141,7 @@ const config = { authPortalUrl: 'https://account-dev.mongodb.com/account/login', }, 'atlas-dev': { - wsBaseUrl: '', + ccsBaseUrl: '', cloudBaseUrl: '', atlasApiBaseUrl: 'https://cloud-dev.mongodb.com/api/private', atlasLogin: { @@ -151,7 +151,7 @@ const config = { authPortalUrl: 'https://account-dev.mongodb.com/account/login', }, 'atlas-qa': { - wsBaseUrl: '', + ccsBaseUrl: '', cloudBaseUrl: '', atlasApiBaseUrl: 'https://cloud-qa.mongodb.com/api/private', atlasLogin: { @@ -161,7 +161,7 @@ const config = { authPortalUrl: 'https://account-qa.mongodb.com/account/login', }, atlas: { - wsBaseUrl: '', + ccsBaseUrl: '', cloudBaseUrl: '', atlasApiBaseUrl: 'https://cloud.mongodb.com/api/private', atlasLogin: { @@ -171,7 +171,7 @@ const config = { authPortalUrl: 'https://account.mongodb.com/account/login', }, 'web-sandbox-atlas-local': { - wsBaseUrl: '/ccs', + ccsBaseUrl: '/ccs', cloudBaseUrl: '/cloud-mongodb-com', atlasApiBaseUrl: 'http://localhost:8080/api/private', atlasLogin: { @@ -181,7 +181,7 @@ const config = { authPortalUrl: 'https://account-dev.mongodb.com/account/login', }, 'web-sandbox-atlas-dev': { - wsBaseUrl: '/ccs', + ccsBaseUrl: '/ccs', cloudBaseUrl: '/cloud-mongodb-com', atlasApiBaseUrl: 'https://cloud-dev.mongodb.com/api/private', atlasLogin: { @@ -191,7 +191,7 @@ const config = { authPortalUrl: 'https://account-dev.mongodb.com/account/login', }, 'web-sandbox-atlas-qa': { - wsBaseUrl: '/ccs', + ccsBaseUrl: '/ccs', cloudBaseUrl: '/cloud-mongodb-com', atlasApiBaseUrl: 'https://cloud-dev.mongodb.com/api/private', atlasLogin: { @@ -201,7 +201,7 @@ const config = { authPortalUrl: 'https://account-dev.mongodb.com/account/login', }, 'web-sandbox-atlas': { - wsBaseUrl: '/ccs', + ccsBaseUrl: '/ccs', cloudBaseUrl: '/cloud-mongodb-com', atlasApiBaseUrl: 'https://cloud.mongodb.com/api/private', atlasLogin: { diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index 3669630767a..3aab9ca8afa 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -426,10 +426,12 @@ describe('user-data', function () { describe('AtlasUserData', function () { let sandbox: sinon.SinonSandbox; let authenticatedFetchStub: sinon.SinonStub; + let getResourceUrlStub: sinon.SinonStub; beforeEach(function () { sandbox = sinon.createSandbox(); authenticatedFetchStub = sandbox.stub(); + getResourceUrlStub = sandbox.stub(); }); afterEach(function () { @@ -439,15 +441,19 @@ describe('AtlasUserData', function () { const getAtlasUserData = ( validatorOpts: ValidatorOptions = {}, orgId = 'test-org', - groupId = 'test-group', - type: 'favorites' | 'recents' | 'pipelines' = 'favorites' + projectId = 'test-proj', + type: + | 'recentQueries' + | 'favoriteQueries' + | 'favoriteAggregations' = 'favoriteQueries' ) => { return new AtlasUserData( getTestSchema(validatorOpts), - authenticatedFetchStub, - orgId, - groupId, type, + orgId, + projectId, + getResourceUrlStub, + authenticatedFetchStub, {} ); }; @@ -464,6 +470,9 @@ describe('AtlasUserData', function () { context('AtlasUserData.write', function () { it('writes data successfully', async function () { authenticatedFetchStub.resolves(mockResponse({})); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); const result = await userData.write('test-id', { name: 'VSCode' }); @@ -473,14 +482,14 @@ describe('AtlasUserData', function () { const [url, options] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/favorites/test-org/test-group' + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' ); expect(options.method).to.equal('POST'); expect(options.headers['Content-Type']).to.equal('application/json'); const body = JSON.parse(options.body as string); expect(body.id).to.equal('test-id'); - expect(body.groupId).to.equal('test-group'); + expect(body.projectId).to.equal('test-proj'); expect(body.data).to.be.a('string'); expect(JSON.parse(body.data as string)).to.deep.equal({ name: 'VSCode' }); expect(body.createdAt).to.be.a('string'); @@ -489,6 +498,9 @@ describe('AtlasUserData', function () { it('returns false when response is not ok', async function () { authenticatedFetchStub.resolves(mockResponse({}, false, 500)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); @@ -498,6 +510,9 @@ describe('AtlasUserData', function () { it('validator removes unknown props', async function () { authenticatedFetchStub.resolves(mockResponse({})); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); @@ -511,13 +526,17 @@ describe('AtlasUserData', function () { it('uses custom serializer when provided', async function () { authenticatedFetchStub.resolves(mockResponse({})); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = new AtlasUserData( getTestSchema(), - authenticatedFetchStub, + 'favoriteQueries', 'test-org', - 'test-group', - 'favorites', + 'test-proj', + getResourceUrlStub, + authenticatedFetchStub, { serialize: (data) => `custom:${JSON.stringify(data)}`, } @@ -534,6 +553,9 @@ describe('AtlasUserData', function () { context('AtlasUserData.delete', function () { it('deletes data successfully', async function () { authenticatedFetchStub.resolves(mockResponse({})); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj/test-id' + ); const userData = getAtlasUserData(); const result = await userData.delete('test-id'); @@ -543,13 +565,16 @@ describe('AtlasUserData', function () { const [url, options] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/favorites/test-org/test-group/test-id' + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj/test-id' ); expect(options.method).to.equal('DELETE'); }); it('returns false when response is not ok', async function () { authenticatedFetchStub.resolves(mockResponse({}, false, 404)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); @@ -565,6 +590,9 @@ describe('AtlasUserData', function () { { data: JSON.stringify({ name: 'Mongosh' }) }, ]; authenticatedFetchStub.resolves(mockResponse(responseData)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); const result = await userData.readAll(); @@ -591,13 +619,16 @@ describe('AtlasUserData', function () { expect(authenticatedFetchStub).to.have.been.calledOnce; const [url, options] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/favorites/test-org/test-group' + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' ); expect(options.method).to.equal('GET'); }); it('handles empty response', async function () { authenticatedFetchStub.resolves(mockResponse([])); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); const result = await userData.readAll(); @@ -608,6 +639,9 @@ describe('AtlasUserData', function () { it('handles non-array response', async function () { authenticatedFetchStub.resolves(mockResponse({ notAnArray: true })); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); const result = await userData.readAll(); @@ -618,6 +652,9 @@ describe('AtlasUserData', function () { it('handles errors gracefully', async function () { authenticatedFetchStub.rejects(new Error('Unknown error')); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); const result = await userData.readAll(); @@ -629,6 +666,9 @@ describe('AtlasUserData', function () { it('handles non-ok response gracefully', async function () { authenticatedFetchStub.resolves(mockResponse({}, false, 500)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); const result = await userData.readAll(); @@ -641,13 +681,17 @@ describe('AtlasUserData', function () { it('uses custom deserializer when provided', async function () { const responseData = [{ data: 'custom:{"name":"Custom"}' }]; authenticatedFetchStub.resolves(mockResponse(responseData)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = new AtlasUserData( getTestSchema(), - authenticatedFetchStub, + 'favoriteQueries', 'test-org', - 'test-group', - 'favorites', + 'test-proj', + getResourceUrlStub, + authenticatedFetchStub, { deserialize: (data) => { if (data.startsWith('custom:')) { @@ -678,6 +722,9 @@ describe('AtlasUserData', function () { }, ]; authenticatedFetchStub.resolves(mockResponse(responseData)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); const result = await userData.readAll(); @@ -696,6 +743,9 @@ describe('AtlasUserData', function () { it('updates data successfully', async function () { const putResponse = { name: 'Updated Name', hasDarkMode: false }; authenticatedFetchStub.resolves(mockResponse(putResponse)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj/test-id' + ); const userData = getAtlasUserData(); const result = await userData.updateAttributes('test-id', { @@ -708,7 +758,7 @@ describe('AtlasUserData', function () { expect(authenticatedFetchStub).to.have.been.calledOnce; const [url, options] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/favorites/test-org/test-group/test-id' + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj/test-id' ); expect(options.method).to.equal('PUT'); expect(options.headers['Content-Type']).to.equal('application/json'); @@ -716,6 +766,9 @@ describe('AtlasUserData', function () { it('returns false when response is not ok', async function () { authenticatedFetchStub.resolves(mockResponse({}, false, 400)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = getAtlasUserData(); @@ -728,13 +781,17 @@ describe('AtlasUserData', function () { it('uses custom serializer for request body', async function () { const putResponse = { name: 'Updated' }; authenticatedFetchStub.resolves(mockResponse(putResponse)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + ); const userData = new AtlasUserData( getTestSchema(), - authenticatedFetchStub, + 'favoriteQueries', 'test-org', - 'test-group', - 'favorites', + 'test-proj', + getResourceUrlStub, + authenticatedFetchStub, { serialize: (data) => `custom:${JSON.stringify(data)}`, } @@ -750,62 +807,83 @@ describe('AtlasUserData', function () { context('AtlasUserData urls', function () { it('constructs URL correctly for write operation', async function () { authenticatedFetchStub.resolves(mockResponse({})); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/custom-org/custom-proj' + ); - const userData = getAtlasUserData({}, 'custom-org', 'custom-group'); + const userData = getAtlasUserData({}, 'custom-org', 'custom-proj'); await userData.write('test-id', { name: 'Test' }); const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/favorites/custom-org/custom-group' + 'cluster-connection.cloud.mongodb.com/favoriteQueries/custom-org/custom-proj' ); }); it('constructs URL correctly for delete operation', async function () { authenticatedFetchStub.resolves(mockResponse({})); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/org123/proj456/item789' + ); - const userData = getAtlasUserData({}, 'org123', 'group456'); + const userData = getAtlasUserData({}, 'org123', 'proj456'); await userData.delete('item789'); const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/favorites/org123/group456/item789' + 'cluster-connection.cloud.mongodb.com/favoriteQueries/org123/proj456/item789' ); }); it('constructs URL correctly for read operation', async function () { authenticatedFetchStub.resolves(mockResponse({})); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/org456/proj123' + ); + + const userData = getAtlasUserData({}, 'org456', 'proj123'); - const userData = getAtlasUserData({}, 'org456', 'group123'); await userData.readAll(); const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/favorites/org456/group123' + 'cluster-connection.cloud.mongodb.com/favoriteQueries/org456/proj123' ); }); it('constructs URL correctly for update operation', async function () { const putResponse = { data: { name: 'Updated' } }; authenticatedFetchStub.resolves(mockResponse(putResponse)); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/favoriteQueries/org123/proj456/item789' + ); - const userData = getAtlasUserData({}, 'org123', 'group456'); + const userData = getAtlasUserData({}, 'org123', 'proj456'); await userData.updateAttributes('item789', { name: 'Updated' }); const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/favorites/org123/group456/item789' + 'cluster-connection.cloud.mongodb.com/favoriteQueries/org123/proj456/item789' ); }); it('constructs URL correctly for different types', async function () { authenticatedFetchStub.resolves(mockResponse({})); + getResourceUrlStub.resolves( + 'cluster-connection.cloud.mongodb.com/recentQueries/org123/proj456' + ); - const userData = getAtlasUserData({}, 'org123', 'group456', 'recents'); + const userData = getAtlasUserData( + {}, + 'org123', + 'proj456', + 'recentQueries' + ); await userData.write('item789', { name: 'Recent Item' }); const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud-local.mongodb.com/recents/org123/group456' + 'cluster-connection.cloud.mongodb.com/recentQueries/org123/proj456' ); }); }); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index e7bed19255b..fcffd95af22 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -340,25 +340,30 @@ export class FileUserData extends IUserData { // TODO: update endpoints to reflect the merged api endpoints https://jira.mongodb.org/browse/CLOUDP-329716 export class AtlasUserData extends IUserData { private readonly authenticatedFetch; + private readonly getResourceUrl; private orgId: string = ''; - private groupId: string = ''; - private readonly type: 'recents' | 'favorites' | 'pipelines'; - private readonly BASE_URL = 'cluster-connection.cloud-local.mongodb.com'; + private projectId: string = ''; + private readonly type: + | 'recentQueries' + | 'favoriteQueries' + | 'favoriteAggregations'; constructor( validator: T, + type: 'recentQueries' | 'favoriteQueries' | 'favoriteAggregations', + orgId: string, + projectId: string, + getResourceUrl: (path?: string) => Promise, authenticatedFetch: ( url: RequestInfo | URL, options?: RequestInit ) => Promise, - orgId: string, - groupId: string, - type: 'recents' | 'favorites' | 'pipelines', { serialize, deserialize }: AtlasUserDataOptions> ) { super(validator, { serialize, deserialize }); this.authenticatedFetch = authenticatedFetch; + this.getResourceUrl = getResourceUrl; this.orgId = orgId; - this.groupId = groupId; + this.projectId = projectId; this.type = type; } @@ -366,18 +371,23 @@ export class AtlasUserData extends IUserData { try { this.validator.parse(content); - const response = await this.authenticatedFetch(this.getUrl(), { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - id: id, - data: this.serialize(content), - createdAt: new Date(), - groupId: this.groupId, - }), - }); + const response = await this.authenticatedFetch( + await this.getResourceUrl( + `${this.type}/${this.orgId}/${this.projectId}` + ), + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + id: id, + data: this.serialize(content), + createdAt: new Date(), + projectId: this.projectId, + }), + } + ); if (!response.ok) { throw new Error( @@ -392,7 +402,9 @@ export class AtlasUserData extends IUserData { 'Atlas Backend', 'Error writing data', { - url: this.getUrl(), + url: await this.getResourceUrl( + `${this.type}/${this.orgId}/${this.projectId}` + ), error: (error as Error).message, } ); @@ -402,9 +414,14 @@ export class AtlasUserData extends IUserData { async delete(id: string): Promise { try { - const response = await this.authenticatedFetch(this.getUrl() + `/${id}`, { - method: 'DELETE', - }); + const response = await this.authenticatedFetch( + await this.getResourceUrl( + `${this.type}/${this.orgId}/${this.projectId}/${id}` + ), + { + method: 'DELETE', + } + ); if (!response.ok) { throw new Error( `Failed to delete data: ${response.status} ${response.statusText}` @@ -417,7 +434,9 @@ export class AtlasUserData extends IUserData { 'Atlas Backend', 'Error deleting data', { - url: this.getUrl(), + url: await this.getResourceUrl( + `${this.type}/${this.orgId}/${this.projectId}/${id}` + ), error: (error as Error).message, } ); @@ -431,9 +450,14 @@ export class AtlasUserData extends IUserData { errors: [], }; try { - const response = await this.authenticatedFetch(this.getUrl(), { - method: 'GET', - }); + const response = await this.authenticatedFetch( + await this.getResourceUrl( + `${this.type}/${this.orgId}/${this.projectId}` + ), + { + method: 'GET', + } + ); if (!response.ok) { throw new Error( `Failed to get data: ${response.status} ${response.statusText}` @@ -460,13 +484,18 @@ export class AtlasUserData extends IUserData { data: Partial> ): Promise { try { - const response = await this.authenticatedFetch(this.getUrl() + `/${id}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: this.serialize(data), - }); + const response = await this.authenticatedFetch( + await this.getResourceUrl( + `${this.type}/${this.orgId}/${this.projectId}/${id}` + ), + { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: this.serialize(data), + } + ); if (!response.ok) { throw new Error( `Failed to update data: ${response.status} ${response.statusText}` @@ -479,15 +508,13 @@ export class AtlasUserData extends IUserData { 'Atlas Backend', 'Error updating data', { - url: this.getUrl(), + url: await this.getResourceUrl( + `${this.type}/${this.orgId}/${this.projectId}/${id}` + ), error: (error as Error).message, } ); return false; } } - - private getUrl() { - return `${this.BASE_URL}/${this.type}/${this.orgId}/${this.groupId}`; - } } From 3c033feab6dd9b5347d8f437203b0cdaaaf8517e Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Tue, 22 Jul 2025 13:39:20 -0400 Subject: [PATCH 18/26] change wsBaseUrl to ccsBaseUrl in spec files --- packages/atlas-service/src/atlas-service.spec.ts | 2 +- packages/atlas-service/src/main.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/atlas-service/src/atlas-service.spec.ts b/packages/atlas-service/src/atlas-service.spec.ts index b63d7a9a1d6..166f226bf58 100644 --- a/packages/atlas-service/src/atlas-service.spec.ts +++ b/packages/atlas-service/src/atlas-service.spec.ts @@ -7,7 +7,7 @@ import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { CompassAtlasAuthService } from './compass-atlas-auth-service'; const ATLAS_CONFIG = { - wsBaseUrl: 'ws://example.com', + ccsBaseUrl: 'ws://example.com', cloudBaseUrl: 'ws://example.com/cloud', atlasApiBaseUrl: 'http://example.com/api', atlasLogin: { diff --git a/packages/atlas-service/src/main.spec.ts b/packages/atlas-service/src/main.spec.ts index 5f9bec8c48f..350ae78ca8f 100644 --- a/packages/atlas-service/src/main.spec.ts +++ b/packages/atlas-service/src/main.spec.ts @@ -48,7 +48,7 @@ describe('CompassAuthServiceMain', function () { }; const defaultConfig = { - wsBaseUrl: 'ws://example.com', + ccsBaseUrl: 'ws://example.com', cloudBaseUrl: 'ws://example.com/cloud', atlasApiBaseUrl: 'http://example.com/api', atlasLogin: { From ef94ff861f4c268b7dee8ddad851f1c3a586b167 Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 23 Jul 2025 11:49:00 +0200 Subject: [PATCH 19/26] chore(user-data): remove redundant withStats methods --- .../src/user-storage.ts | 4 - .../compass-user-data/src/user-data.spec.ts | 54 ------- packages/compass-user-data/src/user-data.ts | 139 +++++------------- .../src/compass-pipeline-storage.ts | 25 +--- .../src/pipeline-storage-schema.ts | 4 +- 5 files changed, 39 insertions(+), 187 deletions(-) diff --git a/packages/compass-preferences-model/src/user-storage.ts b/packages/compass-preferences-model/src/user-storage.ts index fbaed7f7b27..941c3f25065 100644 --- a/packages/compass-preferences-model/src/user-storage.ts +++ b/packages/compass-preferences-model/src/user-storage.ts @@ -79,8 +79,4 @@ export class UserStorageImpl implements UserStorage { await this.userData.write(user.id, user); return this.getUser(user.id); } - - private getFileName(id: string) { - return `${id}.json`; - } } diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index 155a020092a..e610a072fb9 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -125,39 +125,6 @@ describe('user-data', function () { expect(result.data).to.have.lengthOf(0); expect(result.errors).to.have.lengthOf(2); }); - - it('returns file stats', async function () { - await Promise.all( - [ - ['data1.json', JSON.stringify({ name: 'VSCode' })], - ['data2.json', JSON.stringify({ name: 'Mongosh' })], - ].map(([filepath, data]) => writeFileToStorage(filepath, data)) - ); - - const { data } = await getUserData().readAllWithStats({ - ignoreErrors: true, - }); - - { - const vscodeData = data.find((x) => x[0].name === 'VSCode'); - expect(vscodeData?.[0]).to.deep.equal({ - name: 'VSCode', - hasDarkMode: true, - hasWebSupport: false, - }); - expect(vscodeData?.[1]).to.be.instanceOf(Stats); - } - - { - const mongoshData = data.find((x) => x[0].name === 'Mongosh'); - expect(mongoshData?.[0]).to.deep.equal({ - name: 'Mongosh', - hasDarkMode: true, - hasWebSupport: false, - }); - expect(mongoshData?.[1]).to.be.instanceOf(Stats); - } - }); }); context('UserData.readOne', function () { @@ -302,27 +269,6 @@ describe('user-data', function () { company: 'MongoDB', }); }); - - it('return file stats', async function () { - await writeFileToStorage( - 'data.json', - JSON.stringify({ - name: 'Mongosh', - company: 'MongoDB', - }) - ); - - const [data, stats] = await getUserData().readOneWithStats('data', { - ignoreErrors: false, - }); - - expect(data).to.deep.equal({ - name: 'Mongosh', - hasDarkMode: true, - hasWebSupport: false, - }); - expect(stats).to.be.instanceOf(Stats); - }); }); context('UserData.write', function () { diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index ec4cad6868f..1216f151e79 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -10,14 +10,12 @@ const { log, mongoLogId } = createLogger('COMPASS-USER-STORAGE'); type SerializeContent = (content: I) => string; type DeserializeContent = (content: string) => unknown; -type GetFileName = (id: string) => string; export type FileUserDataOptions = { subdir: string; basePath?: string; serialize?: SerializeContent; deserialize?: DeserializeContent; - getFileName?: GetFileName; }; export type AtlasUserDataOptions = { @@ -29,45 +27,11 @@ type ReadOptions = { ignoreErrors: boolean; }; -// Copied from the Node.js fs module. -export interface Stats { - isFile(): boolean; - isDirectory(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - dev: number; - ino: number; - mode: number; - nlink: number; - uid: number; - gid: number; - rdev: number; - size: number; - blksize: number; - blocks: number; - atimeMs: number; - mtimeMs: number; - ctimeMs: number; - birthtimeMs: number; - atime: Date; - mtime: Date; - ctime: Date; - birthtime: Date; -} - export interface ReadAllResult { data: z.output[]; errors: Error[]; } -export interface ReadAllWithStatsResult { - data: [z.output, Stats][]; - errors: Error[]; -} - export abstract class IUserData { protected readonly validator: T; protected readonly serialize: SerializeContent>; @@ -100,7 +64,6 @@ export abstract class IUserData { export class FileUserData extends IUserData { private readonly subdir: string; private readonly basePath?: string; - private readonly getFileName: GetFileName; protected readonly semaphore = new Semaphore(100); constructor( @@ -110,13 +73,15 @@ export class FileUserData extends IUserData { basePath, serialize, deserialize, - getFileName = (id) => `${id}.json`, }: FileUserDataOptions> ) { super(validator, { serialize, deserialize }); this.subdir = subdir; this.basePath = basePath; - this.getFileName = getFileName; + } + + private getFileName(id: string) { + return `${id}.json`; } private async getEnsuredBasePath(): Promise { @@ -148,21 +113,15 @@ export class FileUserData extends IUserData { return path.resolve(root, pathRelativeToRoot); } - private async readAndParseFileWithStats( + private async readAndParseFile( absolutePath: string, options: ReadOptions - ): Promise<[z.output, Stats] | undefined> { + ): Promise | undefined> { let data: string; - let stats: Stats; - let handle: fs.FileHandle | undefined = undefined; let release: (() => void) | undefined = undefined; try { release = await this.semaphore.waitForRelease(); - handle = await fs.open(absolutePath, 'r'); - [stats, data] = await Promise.all([ - handle.stat(), - handle.readFile('utf-8'), - ]); + data = await fs.readFile(absolutePath, 'utf-8'); } catch (error) { log.error(mongoLogId(1_001_000_234), 'Filesystem', 'Error reading file', { path: absolutePath, @@ -173,13 +132,12 @@ export class FileUserData extends IUserData { } throw error; } finally { - await handle?.close(); release?.(); } try { const content = this.deserialize(data); - return [this.validator.parse(content), stats]; + return this.validator.parse(content); } catch (error) { log.error(mongoLogId(1_001_000_235), 'Filesystem', 'Error parsing data', { path: absolutePath, @@ -235,70 +193,37 @@ export class FileUserData extends IUserData { } } - async readAllWithStats( + async readAll( options: ReadOptions = { ignoreErrors: true, } - ): Promise> { - const absolutePath = await this.getFileAbsolutePath(); - const filePathList = await fs.readdir(absolutePath); - - const data = await Promise.allSettled( - filePathList.map((x) => - this.readAndParseFileWithStats(path.join(absolutePath, x), options) - ) - ); - - const result: ReadAllWithStatsResult = { + ): Promise> { + const result: ReadAllResult = { data: [], errors: [], }; - - for (const item of data) { - if (item.status === 'fulfilled' && item.value) { - result.data.push(item.value); + try { + const absolutePath = await this.getFileAbsolutePath(); + const filePathList = await fs.readdir(absolutePath); + for (const settled of await Promise.allSettled( + filePathList.map((x) => { + return this.readAndParseFile(path.join(absolutePath, x), options); + }) + )) { + if (settled.status === 'fulfilled' && settled.value) { + result.data.push(settled.value); + } + if (settled.status === 'rejected') { + result.errors.push(settled.reason); + } } - if (item.status === 'rejected') { - result.errors.push(item.reason); + return result; + } catch (err) { + if (options.ignoreErrors) { + return result; } + throw err; } - - return result; - } - - async readOneWithStats( - id: string, - options?: { ignoreErrors: false } - ): Promise<[z.output, Stats]>; - async readOneWithStats( - id: string, - options?: { ignoreErrors: true } - ): Promise<[z.output, Stats] | undefined>; - async readOneWithStats( - id: string, - options?: ReadOptions - ): Promise<[z.output, Stats] | undefined>; - async readOneWithStats( - id: string, - options: ReadOptions = { - ignoreErrors: true, - } - ) { - const filepath = this.getFileName(id); - const absolutePath = await this.getFileAbsolutePath(filepath); - return await this.readAndParseFileWithStats(absolutePath, options); - } - - async readAll( - options: ReadOptions = { - ignoreErrors: true, - } - ): Promise> { - const result = await this.readAllWithStats(options); - return { - data: result.data.map(([data]) => data), - errors: result.errors, - }; } async readOne( @@ -319,7 +244,9 @@ export class FileUserData extends IUserData { ignoreErrors: true, } ) { - return (await this.readOneWithStats(id, options))?.[0]; + const filepath = this.getFileName(id); + const absolutePath = await this.getFileAbsolutePath(filepath); + return await this.readAndParseFile(absolutePath, options); } async updateAttributes( diff --git a/packages/my-queries-storage/src/compass-pipeline-storage.ts b/packages/my-queries-storage/src/compass-pipeline-storage.ts index 766fc0166a0..9b9f868a71d 100644 --- a/packages/my-queries-storage/src/compass-pipeline-storage.ts +++ b/packages/my-queries-storage/src/compass-pipeline-storage.ts @@ -1,4 +1,3 @@ -import type { Stats } from '@mongodb-js/compass-user-data'; import { FileUserData } from '@mongodb-js/compass-user-data'; import { PipelineSchema } from './pipeline-storage-schema'; import type { SavedPipeline } from './pipeline-storage-schema'; @@ -13,21 +12,10 @@ export class CompassPipelineStorage implements PipelineStorage { }); } - private mergeStats(pipeline: SavedPipeline, stats: Stats): SavedPipeline { - return { - ...pipeline, - lastModified: new Date(stats.ctimeMs), - }; - } - async loadAll(): Promise { try { - const { data } = await this.userData.readAllWithStats({ - ignoreErrors: false, - }); - return data.map(([item, stats]) => { - return this.mergeStats(item, stats); - }); + const { data } = await this.userData.readAll(); + return data; } catch { return []; } @@ -41,16 +29,11 @@ export class CompassPipelineStorage implements PipelineStorage { } private async loadOne(id: string): Promise { - const [item, stats] = await this.userData.readOneWithStats(id); - return this.mergeStats(item, stats); + return await this.userData.readOne(id); } async createOrUpdate(id: string, attributes: SavedPipeline) { - const pipelineExists = Boolean( - await this.userData.readOne(id, { - ignoreErrors: true, - }) - ); + const pipelineExists = Boolean(await this.userData.readOne(id)); return await (pipelineExists ? this.updateAttributes(id, attributes) : this.create(attributes)); diff --git a/packages/my-queries-storage/src/pipeline-storage-schema.ts b/packages/my-queries-storage/src/pipeline-storage-schema.ts index 35bfbe53ada..9173c4eea24 100644 --- a/packages/my-queries-storage/src/pipeline-storage-schema.ts +++ b/packages/my-queries-storage/src/pipeline-storage-schema.ts @@ -62,8 +62,8 @@ export const PipelineSchema = z.preprocess( pipelineText: z.string(), lastModified: z .number() - .transform((x) => new Date(x)) - .optional(), + .default(0) + .transform((x) => new Date(x)), }) ); From 3f8405add6f40c867e9073216e467929fbb6e78c Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 23 Jul 2025 13:17:18 +0200 Subject: [PATCH 20/26] fix(user-data): remove nonexistent exports --- packages/compass-user-data/src/index.ts | 2 +- packages/compass-user-data/src/user-data.spec.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/compass-user-data/src/index.ts b/packages/compass-user-data/src/index.ts index b216fd77f99..14a3b49677c 100644 --- a/packages/compass-user-data/src/index.ts +++ b/packages/compass-user-data/src/index.ts @@ -1,3 +1,3 @@ -export type { Stats, ReadAllResult, ReadAllWithStatsResult } from './user-data'; +export type { ReadAllResult } from './user-data'; export { IUserData, FileUserData } from './user-data'; export { z } from 'zod'; diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index e610a072fb9..88c785a2dc9 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -1,5 +1,4 @@ import fs from 'fs/promises'; -import { Stats } from 'fs'; import os from 'os'; import path from 'path'; import { expect } from 'chai'; From 7f07ddd8d611926679bba0df10ae03eb475fb146 Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 23 Jul 2025 16:25:04 +0200 Subject: [PATCH 21/26] fix(my-queries-storage): adjust types to match the method behavior --- .../my-queries-storage/src/compass-pipeline-storage.ts | 7 +++++-- packages/my-queries-storage/src/pipeline-storage.ts | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/my-queries-storage/src/compass-pipeline-storage.ts b/packages/my-queries-storage/src/compass-pipeline-storage.ts index 9b9f868a71d..069707ae1e7 100644 --- a/packages/my-queries-storage/src/compass-pipeline-storage.ts +++ b/packages/my-queries-storage/src/compass-pipeline-storage.ts @@ -32,14 +32,17 @@ export class CompassPipelineStorage implements PipelineStorage { return await this.userData.readOne(id); } - async createOrUpdate(id: string, attributes: SavedPipeline) { + async createOrUpdate( + id: string, + attributes: Omit + ) { const pipelineExists = Boolean(await this.userData.readOne(id)); return await (pipelineExists ? this.updateAttributes(id, attributes) : this.create(attributes)); } - private async create(data: SavedPipeline) { + private async create(data: Omit) { await this.userData.write(data.id, { ...data, lastModified: Date.now(), diff --git a/packages/my-queries-storage/src/pipeline-storage.ts b/packages/my-queries-storage/src/pipeline-storage.ts index 7924645e6fe..faca39feb35 100644 --- a/packages/my-queries-storage/src/pipeline-storage.ts +++ b/packages/my-queries-storage/src/pipeline-storage.ts @@ -5,7 +5,10 @@ export interface PipelineStorage { loadMany( predicate: (arg0: SavedPipeline) => boolean ): Promise; - createOrUpdate(id: string, attributes: SavedPipeline): Promise; + createOrUpdate( + id: string, + attributes: Omit + ): Promise; updateAttributes( id: string, attributes: Partial From e09d426222a3c2bdf66130916109159f052b92ce Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 23 Jul 2025 16:53:32 +0200 Subject: [PATCH 22/26] fix(saved-aggregations-queries): adjust test fixture --- .../compass-saved-aggregations-queries/src/index.spec.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/compass-saved-aggregations-queries/src/index.spec.tsx b/packages/compass-saved-aggregations-queries/src/index.spec.tsx index eb1f7d1686d..b7cff3427ca 100644 --- a/packages/compass-saved-aggregations-queries/src/index.spec.tsx +++ b/packages/compass-saved-aggregations-queries/src/index.spec.tsx @@ -227,9 +227,11 @@ describe('AggregationsAndQueriesAndUpdatemanyList', function () { queryStorageLoadAllStub = sandbox .stub(queryStorage, 'loadAll') .resolves(queries.map((item) => item.query)); - sandbox - .stub(pipelineStorage, 'loadAll') - .resolves(pipelines.map((item) => item.aggregation)); + sandbox.stub(pipelineStorage, 'loadAll').resolves( + pipelines.map((item) => { + return { ...item.aggregation, lastModified: new Date() }; + }) + ); renderPlugin(); From 04ba804f7dd24b281b742b557c93ee72c48e1b5c Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Wed, 23 Jul 2025 16:36:42 -0400 Subject: [PATCH 23/26] put data type in IUserData class --- packages/atlas-service/src/secret-store.ts | 3 +- .../lib/symbol-table/shelltocsharp.js | 3 +- .../lib/symbol-table/shelltogo.js | 3 +- .../lib/symbol-table/shelltojava.js | 3 +- .../lib/symbol-table/shelltojavascript.js | 3 +- .../lib/symbol-table/shelltoobject.js | 3 +- .../lib/symbol-table/shelltophp.js | 3 +- .../lib/symbol-table/shelltopython.js | 3 +- .../lib/symbol-table/shelltoruby.js | 3 +- .../lib/symbol-table/shelltorust.js | 3 +- .../services/data-model-storage-electron.tsx | 11 +- .../src/preferences-persistent-storage.ts | 11 +- .../src/user-storage.ts | 3 +- .../src/modules/history-storage.ts | 3 +- .../compass-user-data/src/user-data.spec.ts | 110 +++++++----------- packages/compass-user-data/src/user-data.ts | 47 ++++---- .../src/compass-main-connection-storage.ts | 3 +- .../src/compass-pipeline-storage.ts | 5 +- .../src/compass-query-storage.ts | 3 +- .../src/pipeline-storage.ts | 1 + 20 files changed, 104 insertions(+), 123 deletions(-) diff --git a/packages/atlas-service/src/secret-store.ts b/packages/atlas-service/src/secret-store.ts index a303151250f..a75ffd2ba36 100644 --- a/packages/atlas-service/src/secret-store.ts +++ b/packages/atlas-service/src/secret-store.ts @@ -7,8 +7,7 @@ export class SecretStore { private readonly userData: FileUserData; private readonly fileName = 'AtlasPluginState'; constructor(basePath?: string) { - this.userData = new FileUserData(AtlasPluginStateSchema, { - subdir: 'AtlasState', + this.userData = new FileUserData(AtlasPluginStateSchema, 'AtlasState', { basePath, }); } diff --git a/packages/bson-transpilers/lib/symbol-table/shelltocsharp.js b/packages/bson-transpilers/lib/symbol-table/shelltocsharp.js index d50493e1129..bbc2db47ca2 100644 --- a/packages/bson-transpilers/lib/symbol-table/shelltocsharp.js +++ b/packages/bson-transpilers/lib/symbol-table/shelltocsharp.js @@ -1 +1,2 @@ -module.exports="SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n\n# C# Templates\nTemplates:\n # Misc\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: ''\n y: ''\n g: ''\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: ''\n u: ''\n # Syntax\n DriverTemplate: &DriverTemplate null\n EqualitySyntaxTemplate: &EqualitySyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n }\n else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: &InSyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n let str = '!=';\n if (op.includes('!') || op.includes('not')) {\n str = '==';\n }\n return `${rhs}.indexOf(${lhs}) ${str} -1`\n }\n AndSyntaxTemplate: &AndSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: &OrSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: &NotSyntaxTemplate !!js/function >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: &BinarySyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `Math.floor(${s}, ${rhs})`;\n case '**':\n return `Math.pow(${s}, ${rhs})`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosSyntaxTemplate: &EosSyntaxTemplate null\n EofSyntaxTemplate: &EofSyntaxTemplate null\n NewTemplate: &NewSyntaxTemplate !!js/function >\n (expr, skip, code) => {\n // Add classes that don't use \"new\" to array\n // So far: [Symbol, Decimal128/NumberDecimal, Long/NumberLong, MinKey, MaxKey, Date.now, Double, Int32, Number, Date]\n noNew = [111, 112, 106, 107, 108, 200.1, 104, 105, 2, 200];\n if (skip || (code && noNew.indexOf(code) !== -1)) {\n return expr;\n }\n return `new ${expr}`;\n }\n # BSON Object Type templates\n CodeTypeTemplate: &CodeTypeTemplate null\n StringTypeTemplate: &StringTypeTemplate !!js/function >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n RegexTypeTemplate: &RegexTypeTemplate !!js/function >\n (pattern, flags) => {\n flags = flags === '' ? '' : `(?${flags})`;\n // Double-quote stringify\n const str = flags + pattern;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `Regex(\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n BoolTypeTemplate: &BoolTypeTemplate !!js/function >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null\n DecimalTypeTemplate: &DecimalTypeTemplate null\n LongBasicTypeTemplate: &LongBasicTypeTemplate null\n HexTypeTemplate: &HexTypeTemplate null\n OctalTypeTemplate: &OctalTypeTemplate !!js/function >\n (literal) => {\n literal = literal.replace(/[oO]+/g, '0')\n return parseInt(literal, 8).toString()\n }\n NumericTypeTemplate: &NumericTypeTemplate null\n ArrayTypeTemplate: &ArrayTypeTemplate !!js/function >\n (literal, depth) => {\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const initialIndent = '\\n' + ' '.repeat(depth-1);\n if (literal === '') {\n return 'new BsonArray()'\n }\n\n return `new BsonArray${initialIndent}{${literal}${initialIndent}}`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate !!js/function >\n (arg, depth, last) => {\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const arr = arg.split(', new').join(`, ${indent}new`)\n\n return last ? `${indent}${arr}` : `${indent}${arr},`;\n }\n NullTypeTemplate: &NullTypeTemplate !!js/function >\n () => {\n return 'BsonNull.Value';\n }\n UndefinedTypeTemplate: &UndefinedTypeTemplate !!js/function >\n () => {\n return 'BsonUndefined.Value';\n }\n ObjectTypeTemplate: &ObjectTypeTemplate !!js/function >\n (literal) => {\n if (literal === '') {\n return `new BsonDocument()`;\n }\n return literal;\n }\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate !!js/function >\n (args, depth) => {\n if (args.length === 0) {\n return 'new BsonDocument()';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const initialIndent = '\\n' + ' '.repeat(depth-1);\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n\n if (args.length === 1) {\n return `new BsonDocument(${doubleStringify(args[0][0])}, ${args[0][1]})`;\n }\n\n const pairs = args.map((pair) => {\n return `${indent}{ ${doubleStringify(pair[0])}, ${pair[1]} }`;\n }).join(', ');\n\n return `new BsonDocument${initialIndent}{${pairs}${initialIndent}}`\n }\n # BSON Object Method templates\n CodeCodeTemplate: &CodeCodeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.Code`;\n }\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.Scope`;\n }\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n # Since in python, generated from attr access instead of func call, add () in template.\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.ToString()`;\n }\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.Equals`;\n }\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n if (arg.indexOf('new') === 0) {\n arg = arg.replace(/new /g, '')\n }\n return `(new ${arg})`;\n }\n\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate !!js/function >\n (lhs) => {\n return `${lhs}.Timestamp`;\n }\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n BinaryValueTemplate: &BinaryValueTemplate !!js/function >\n (lhs) => {\n return `${lhs}.ToString`;\n }\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate !!js/function >\n () => {\n return '';\n }\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.Bytes.Length`;\n }\n BinaryToStringTemplate: &BinaryToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.ToString`;\n }\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: &BinarySubtypeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.SubType`;\n }\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetDBTemplate: &DBRefGetDBTemplate !!js/function >\n (lhs) => {\n return `${lhs}.DatabaseName`;\n }\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate !!js/function >\n (lhs) => {\n return `${lhs}.CollectionName`;\n }\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetIdTemplate: &DBRefGetIdTemplate !!js/function >\n (lhs) => {\n return `${lhs}.Id`;\n }\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongEqualsTemplate: &LongEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} == `;\n }\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n LongToIntTemplate: &LongToIntTemplate !!js/function >\n (lhs) => {\n return `(int) ${lhs}`;\n }\n LongToIntArgsTemplate: &LongToIntArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongToStringTemplate: &LongToStringTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToNumberTemplate: &LongToNumberTemplate !!js/function >\n (lhs) => {\n return `(double) ${lhs}`;\n }\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongAddTemplate: &LongAddTemplate !!js/function >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: &LongAddArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: &LongSubtractTemplate !!js/function >\n (lhs) => {\n return `${lhs} -`;\n }\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: &LongMultiplyTemplate !!js/function >\n (lhs) => {\n return `${lhs} *`;\n }\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: &LongDivTemplate !!js/function >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: &LongDivArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: &LongModuloTemplate !!js/function >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: &LongModuloArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: &LongAndTemplate !!js/function >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: &LongAndArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: &LongOrTemplate !!js/function >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: &LongOrArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: &LongXorTemplate !!js/function >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: &LongXorArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: &LongShiftLeftTemplate !!js/function >\n (lhs) => {\n return `${lhs} <<`;\n }\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftRightTemplate: &LongShiftRightTemplate !!js/function >\n (lhs) => {\n return `${lhs} >>`;\n }\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongCompareTemplate: &LongCompareTemplate !!js/function >\n (lhs) => {\n return `${lhs} - `;\n }\n LongCompareArgsTemplate: &LongCompareArgsTemplate !!js/function >\n (lhs, arg) => {\n return arg;\n }\n LongIsOddTemplate: &LongIsOddTemplate !!js/function >\n (lhs) => {\n return `${lhs}`;\n }\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate !!js/function >\n () => {\n return ' % 2 == 1';\n }\n LongIsZeroTemplate: &LongIsZeroTemplate !!js/function >\n (lhs) => {\n return `${lhs} == 0`;\n }\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongIsNegativeTemplate: &LongIsNegativeTemplate !!js/function >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongNegateTemplate: &LongNegateTemplate !!js/function >\n () => {\n return '-';\n }\n LongNegateArgsTemplate: &LongNegateArgsTemplate !!js/function >\n (lhs) => {\n return `${lhs}`;\n }\n LongNotTemplate: &LongNotTemplate !!js/function >\n () => {\n return '~';\n }\n LongNotArgsTemplate: &LongNotArgsTemplate !!js/function >\n (lhs) => {\n return `${lhs}`;\n }\n LongNotEqualsTemplate: &LongNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: &LongGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: &LongLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: &LongFloatApproxTemplate !!js/function >\n (lhs) => {\n return `(float) ${lhs}`;\n }\n LongTopTemplate: &LongTopTemplate !!js/function >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: &LongBottomTemplate !!js/function >\n (lhs) => {\n return `${lhs} & 0x0000ffff`;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.ToString`;\n }\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n TimestampEqualsTemplate: &TimestampEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.Equals`;\n }\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate null\n TimestampGetLowBitsTemplate: &TimestampGetLowBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.ToUniversalTime`;\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate null\n TimestampGetHighBitsTemplate: &TimestampGetHighBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.Increment`;\n }\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n TimestampTTemplate: &TimestampTTemplate !!js/function >\n (lhs) => {\n return `${lhs}.ToUniversalTime()`;\n }\n TimestampITemplate: &TimestampITemplate !!js/function >\n (lhs) => {\n return `${lhs}.Increment`;\n }\n TimestampAsDateTemplate: &TimestampAsDateTemplate !!js/function >\n (lhs) => {\n return `new DateTime(1970, 1, 1).AddSeconds(${lhs}.Timestamp)`;\n }\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate !!js/function >\n () => {\n return '';\n }\n TimestampCompareTemplate: &TimestampCompareTemplate !!js/function >\n (lhs) => {\n return `${lhs}.CompareTo`;\n }\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate null\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} != `;\n }\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} > `;\n }\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} >= `;\n }\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanTemplate: &TimestampLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} < `;\n }\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} <= `;\n }\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n SymbolValueOfTemplate: &SymbolValueOfTemplate !!js/function >\n (lhs) => {\n return `${lhs}`;\n }\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate !!js/function >\n () => {\n return '';\n }\n SymbolInspectTemplate: &SymbolInspectTemplate !!js/function >\n (lhs) => {\n return `${lhs}`;\n }\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate !!js/function >\n () => {\n return '';\n }\n SymbolToStringTemplate: &SymbolToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}`;\n }\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n # Symbol Templates\n CodeSymbolTemplate: &CodeSymbolTemplate !!js/function > # Also has process method\n () => {\n return 'BsonJavaScript';\n }\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate !!js/function >\n (lhs, code, scope) => {\n // Double quote stringify\n let newStr = code === undefined ? '' : code;\n const str = newStr;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n code = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n return (scope === undefined) ? `(${code})` : `WithScope(${code}, ${scope})`;\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate !!js/function >\n () => {\n return 'ObjectId';\n }\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate !!js/function >\n (lhs, str) => {\n if (!str || str.length === 0) {\n return '()';\n }\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `(\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate !!js/function >\n () => {\n return 'BsonBinaryData';\n }\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate !!js/function >\n (lhs, bytes, type) => {\n const str = bytes;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n bytes = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n\n if (type === null) {\n return `(System.Text.Encoding.ASCII.GetBytes(${bytes}))`;\n }\n return `(System.Text.Encoding.ASCII.GetBytes(${bytes}), ${type})`;\n }\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.Binary';\n }\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.Function';\n }\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.OldBinary';\n }\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.UuidLegacy';\n }\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.UuidStandard';\n }\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template !!js/function >\n () => {\n return 'BsonBinarySubType.MD5';\n }\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.UserDefined';\n }\n DBRefSymbolTemplate: &DBRefSymbolTemplate !!js/function >\n () => {\n return 'MongoDBRef';\n }\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null\n DoubleSymbolTemplate: &DoubleSymbolTemplate !!js/function >\n () => {\n return '';\n }\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n if (type === '_hex') {\n return `Convert.ToDouble(${arg})`;\n }\n if (type === '_string') {\n return `Convert.ToDouble(${arg})`;\n }\n\n if (type === '_decimal') {\n return arg;\n }\n\n return `${Math.round(arg).toFixed(1)}`;\n }\n Int32SymbolTemplate: &Int32SymbolTemplate !!js/function >\n () => {\n return '';\n }\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n if (type === '_hex' || type === '_decimal' || type === '_string') {\n return `Convert.ToInt32(${arg})`;\n }\n\n return arg;\n }\n LongSymbolTemplate: &LongSymbolTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n if (!arg || arg.length === 0) {\n arg = '0';\n }\n if (arg.indexOf('\\'') === 0 || arg.indexOf('\"') === 0) {\n return `Convert.ToInt64(${arg})`;\n }\n return `${arg}L`;\n }\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate !!js/function >\n () => {\n return 'Int64.MaxValue';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate !!js/function >\n () => {\n return 'Int64.MinValue';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate !!js/function >\n (lhs) => {\n return '0L';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate !!js/function >\n (lhs) => {\n return '1L';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate !!js/function >\n (lhs) => {\n return '-1L';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate !!js/function > # Also has process method\n () => {\n return '';\n }\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}L`;\n }\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate null\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate !!js/function >\n () => {\n return 'Convert.ToInt64';\n }\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate !!js/function >\n (lhs, arg1, arg2) => {\n if (arg2) {\n return `(${arg1}, ${arg2})`\n }\n return `(${arg1}, 10)`\n }\n MinKeySymbolTemplate: &MinKeySymbolTemplate !!js/function >\n () => {\n return 'BsonMinKey';\n }\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate !!js/function >\n () => {\n return '.Value';\n }\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate !!js/function >\n () => {\n return 'BsonMaxKey';\n }\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate !!js/function >\n () => {\n return '.Value';\n }\n TimestampSymbolTemplate: &TimestampSymbolTemplate !!js/function >\n () => {\n return 'BsonTimestamp';\n }\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate !!js/function >\n (lhs, arg1, arg2) => {\n if (typeof arg1 === 'undefined') {\n return '(0, 0)'\n }\n return `(${arg1}, ${arg2})`;\n }\n SymbolSymbolTemplate: &SymbolSymbolTemplate !!js/function >\n () => {\n return '';\n }\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate !!js/function >\n (_, arg) => {\n return arg; // no parens because generates as a string\n }\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate !!js/function >\n () => {\n return 'BsonRegularExpression';\n }\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate !!js/function >\n (lhs, pattern, flags) => {\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n return `(${doubleStringify(pattern)}${flags ? ', ' + doubleStringify(flags) : ''})`;\n }\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate !!js/function >\n () => {\n return 'Decimal128';\n }\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate !!js/function >\n (_, str) => { // just stringify\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `.Parse(\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.Parse`;\n }\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg})`;\n }\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.ToString`;\n }\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # BSON Util Templates\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate !!js/function >\n (lhs) => {\n return `new ${lhs}`;\n }\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate null\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate !!js/function >\n () => {\n return `new ObjectId.GenerateNewId`;\n }\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate !!js/function >\n (lhs, arg, isNumber) => {\n if (isNumber) {\n return `(Convert.ToInt32(${arg}))`;\n }\n return `(${arg})`;\n }\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate !!js/function >\n (lhs) => {\n return `new ${lhs}`;\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n # JS Symbol Templates\n NumberSymbolTemplate: &NumberSymbolTemplate !!js/function >\n () => {\n return '';\n }\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n if (type === '_string') {\n if (arg.indexOf('.') !== -1) {\n return `float.Parse(${arg})`\n }\n return `int.Parse(${arg})`;\n }\n\n if (arg.indexOf('.') !== -1) {\n return `(float) ${arg}`\n }\n return `(int) ${arg}`;\n }\n DateSymbolTemplate: &DateSymbolTemplate !!js/function >\n () => {\n return 'DateTime';\n }\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate !!js/function >\n (lhs, date, isString) => {\n let toStr = isString? '.ToString(\"ddd MMM dd yyyy HH\\':\\'mm\\':\\'ss UTC\")' : '';\n\n if (date === null) {\n return `${lhs}.Now${toStr}`;\n }\n\n const dateStr = [\n date.getUTCFullYear(),\n date.getUTCMonth() + 1,\n date.getUTCDate(),\n date.getUTCHours(),\n date.getUTCMinutes(),\n date.getUTCSeconds()\n ].join(', ');\n\n return `new ${lhs}(${dateStr})${toStr}`;\n }\n DateSymbolNowTemplate: &DateSymbolNowTemplate !!js/function >\n () => {\n return 'DateTime.Now';\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate !!js/function >\n () => {\n return '';\n }\n RegExpSymbolTemplate: &RegExpSymbolTemplate !!js/function > # Also has process method\n () => {\n return 'Regex';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null\n ImportTemplate: &ImportTemplate !!js/function >\n (args) => {\n const universal = ['using MongoDB.Bson;', 'using MongoDB.Driver;'];\n const all = universal.concat(Object.values(args));\n return all.join('\\n');\n }\n DriverImportTemplate: &DriverImportTemplate null\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate !!js/function >\n () => {\n return 'using System.Text.RegularExpressions;';\n }\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: &100ImportTemplate null\n 101ImportTemplate: &101ImportTemplate null\n 102ImportTemplate: &102ImportTemplate null\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n 107ImportTemplate: &107ImportTemplate null\n 108ImportTemplate: &108ImportTemplate null\n 109ImportTemplate: &109ImportTemplate null\n 110ImportTemplate: &110ImportTemplate null\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: &112ImportTemplate null\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate !!js/function >\n () => {\n return 'using System;';\n }\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; +module.exports = + 'SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n# C# Templates\nTemplates:\n # Misc\n RegexFlags: &RegexFlags\n i: \'i\'\n m: \'m\'\n u: \'\'\n y: \'\'\n g: \'\'\n BSONRegexFlags: &BSONRegexFlags\n i: \'i\'\n m: \'m\'\n x: \'x\'\n s: \'s\'\n l: \'\'\n u: \'\'\n # Syntax\n DriverTemplate: &DriverTemplate null\n EqualitySyntaxTemplate: !!js/function &EqualitySyntaxTemplate >\n (lhs, op, rhs) => {\n if (op.includes(\'!\') || op.includes(\'not\')) {\n return `${lhs} != ${rhs}`;\n }\n else if (op === \'==\' || op === \'===\' || op === \'is\') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: !!js/function &InSyntaxTemplate >\n (lhs, op, rhs) => {\n let str = \'!=\';\n if (op.includes(\'!\') || op.includes(\'not\')) {\n str = \'==\';\n }\n return `${rhs}.indexOf(${lhs}) ${str} -1`\n }\n AndSyntaxTemplate: !!js/function &AndSyntaxTemplate >\n (args) => {\n return args.join(\' && \');\n }\n OrSyntaxTemplate: !!js/function &OrSyntaxTemplate >\n (args) => {\n return args.join(\' || \');\n }\n NotSyntaxTemplate: !!js/function &NotSyntaxTemplate >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: !!js/function &BinarySyntaxTemplate >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case \'//\':\n return `Math.floor(${s}, ${rhs})`;\n case \'**\':\n return `Math.pow(${s}, ${rhs})`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosSyntaxTemplate: &EosSyntaxTemplate null\n EofSyntaxTemplate: &EofSyntaxTemplate null\n NewTemplate: !!js/function &NewSyntaxTemplate >\n (expr, skip, code) => {\n // Add classes that don\'t use "new" to array\n // So far: [Symbol, Decimal128/NumberDecimal, Long/NumberLong, MinKey, MaxKey, Date.now, Double, Int32, Number, Date]\n noNew = [111, 112, 106, 107, 108, 200.1, 104, 105, 2, 200];\n if (skip || (code && noNew.indexOf(code) !== -1)) {\n return expr;\n }\n return `new ${expr}`;\n }\n # BSON Object Type templates\n CodeTypeTemplate: &CodeTypeTemplate null\n StringTypeTemplate: !!js/function &StringTypeTemplate >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `"${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}"`;\n }\n RegexTypeTemplate: !!js/function &RegexTypeTemplate >\n (pattern, flags) => {\n flags = flags === \'\' ? \'\' : `(?${flags})`;\n // Double-quote stringify\n const str = flags + pattern;\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `Regex("${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}")`;\n }\n BoolTypeTemplate: !!js/function &BoolTypeTemplate >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null\n DecimalTypeTemplate: &DecimalTypeTemplate null\n LongBasicTypeTemplate: &LongBasicTypeTemplate null\n HexTypeTemplate: &HexTypeTemplate null\n OctalTypeTemplate: !!js/function &OctalTypeTemplate >\n (literal) => {\n literal = literal.replace(/[oO]+/g, \'0\')\n return parseInt(literal, 8).toString()\n }\n NumericTypeTemplate: &NumericTypeTemplate null\n ArrayTypeTemplate: !!js/function &ArrayTypeTemplate >\n (literal, depth) => {\n depth++;\n const indent = \'\\n\' + \' \'.repeat(depth);\n const initialIndent = \'\\n\' + \' \'.repeat(depth-1);\n if (literal === \'\') {\n return \'new BsonArray()\'\n }\n\n return `new BsonArray${initialIndent}{${literal}${initialIndent}}`;\n }\n ArrayTypeArgsTemplate: !!js/function &ArrayTypeArgsTemplate >\n (arg, depth, last) => {\n depth++;\n const indent = \'\\n\' + \' \'.repeat(depth);\n const arr = arg.split(\', new\').join(`, ${indent}new`)\n\n return last ? `${indent}${arr}` : `${indent}${arr},`;\n }\n NullTypeTemplate: !!js/function &NullTypeTemplate >\n () => {\n return \'BsonNull.Value\';\n }\n UndefinedTypeTemplate: !!js/function &UndefinedTypeTemplate >\n () => {\n return \'BsonUndefined.Value\';\n }\n ObjectTypeTemplate: !!js/function &ObjectTypeTemplate >\n (literal) => {\n if (literal === \'\') {\n return `new BsonDocument()`;\n }\n return literal;\n }\n ObjectTypeArgsTemplate: !!js/function &ObjectTypeArgsTemplate >\n (args, depth) => {\n if (args.length === 0) {\n return \'new BsonDocument()\';\n }\n depth++;\n const indent = \'\\n\' + \' \'.repeat(depth);\n const initialIndent = \'\\n\' + \' \'.repeat(depth-1);\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `"${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}"`;\n }\n\n if (args.length === 1) {\n return `new BsonDocument(${doubleStringify(args[0][0])}, ${args[0][1]})`;\n }\n\n const pairs = args.map((pair) => {\n return `${indent}{ ${doubleStringify(pair[0])}, ${pair[1]} }`;\n }).join(\', \');\n\n return `new BsonDocument${initialIndent}{${pairs}${initialIndent}}`\n }\n # BSON Object Method templates\n CodeCodeTemplate: !!js/function &CodeCodeTemplate >\n (lhs) => {\n return `${lhs}.Code`;\n }\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: !!js/function &CodeScopeTemplate >\n (lhs) => {\n return `${lhs}.Scope`;\n }\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n # Since in python, generated from attr access instead of func call, add () in template.\n ObjectIdToStringTemplate: !!js/function &ObjectIdToStringTemplate >\n (lhs) => {\n return `${lhs}.ToString()`;\n }\n ObjectIdToStringArgsTemplate: !!js/function &ObjectIdToStringArgsTemplate >\n () => {\n return \'\';\n }\n ObjectIdEqualsTemplate: !!js/function &ObjectIdEqualsTemplate >\n (lhs) => {\n return `${lhs}.Equals`;\n }\n ObjectIdEqualsArgsTemplate: !!js/function &ObjectIdEqualsArgsTemplate >\n (lhs, arg) => {\n if (arg.indexOf(\'new\') === 0) {\n arg = arg.replace(/new /g, \'\')\n }\n return `(new ${arg})`;\n }\n\n ObjectIdGetTimestampTemplate: !!js/function &ObjectIdGetTimestampTemplate >\n (lhs) => {\n return `${lhs}.Timestamp`;\n }\n ObjectIdGetTimestampArgsTemplate:\n !!js/function &ObjectIdGetTimestampArgsTemplate >\n (lhs) => {\n return \'\';\n }\n BinaryValueTemplate: !!js/function &BinaryValueTemplate >\n (lhs) => {\n return `${lhs}.ToString`;\n }\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: !!js/function &BinaryLengthTemplate >\n () => {\n return \'\';\n }\n BinaryLengthArgsTemplate: !!js/function &BinaryLengthArgsTemplate >\n (lhs) => {\n return `${lhs}.Bytes.Length`;\n }\n BinaryToStringTemplate: !!js/function &BinaryToStringTemplate >\n (lhs) => {\n return `${lhs}.ToString`;\n }\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: !!js/function &BinarySubtypeTemplate >\n (lhs) => {\n return `${lhs}.SubType`;\n }\n BinarySubtypeArgsTemplate: !!js/function &BinarySubtypeArgsTemplate >\n () => {\n return \'\';\n }\n DBRefGetDBTemplate: !!js/function &DBRefGetDBTemplate >\n (lhs) => {\n return `${lhs}.DatabaseName`;\n }\n DBRefGetDBArgsTemplate: !!js/function &DBRefGetDBArgsTemplate >\n () => {\n return \'\';\n }\n DBRefGetCollectionTemplate: !!js/function &DBRefGetCollectionTemplate >\n (lhs) => {\n return `${lhs}.CollectionName`;\n }\n DBRefGetCollectionArgsTemplate:\n !!js/function &DBRefGetCollectionArgsTemplate >\n () => {\n return \'\';\n }\n DBRefGetIdTemplate: !!js/function &DBRefGetIdTemplate >\n (lhs) => {\n return `${lhs}.Id`;\n }\n DBRefGetIdArgsTemplate: !!js/function &DBRefGetIdArgsTemplate >\n () => {\n return \'\';\n }\n LongEqualsTemplate: !!js/function &LongEqualsTemplate >\n (lhs) => {\n return `${lhs} == `;\n }\n LongEqualsArgsTemplate: !!js/function &LongEqualsArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n LongToIntTemplate: !!js/function &LongToIntTemplate >\n (lhs) => {\n return `(int) ${lhs}`;\n }\n LongToIntArgsTemplate: !!js/function &LongToIntArgsTemplate >\n () => {\n return \'\';\n }\n LongToStringTemplate: !!js/function &LongToStringTemplate >\n (lhs) => {\n return lhs;\n }\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToNumberTemplate: !!js/function &LongToNumberTemplate >\n (lhs) => {\n return `(double) ${lhs}`;\n }\n LongToNumberArgsTemplate: !!js/function &LongToNumberArgsTemplate >\n () => {\n return \'\';\n }\n LongAddTemplate: !!js/function &LongAddTemplate >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: !!js/function &LongAddArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: !!js/function &LongSubtractTemplate >\n (lhs) => {\n return `${lhs} -`;\n }\n LongSubtractArgsTemplate: !!js/function &LongSubtractArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: !!js/function &LongMultiplyTemplate >\n (lhs) => {\n return `${lhs} *`;\n }\n LongMultiplyArgsTemplate: !!js/function &LongMultiplyArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: !!js/function &LongDivTemplate >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: !!js/function &LongDivArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: !!js/function &LongModuloTemplate >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: !!js/function &LongModuloArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: !!js/function &LongAndTemplate >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: !!js/function &LongAndArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: !!js/function &LongOrTemplate >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: !!js/function &LongOrArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: !!js/function &LongXorTemplate >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: !!js/function &LongXorArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: !!js/function &LongShiftLeftTemplate >\n (lhs) => {\n return `${lhs} <<`;\n }\n LongShiftLeftArgsTemplate: !!js/function &LongShiftLeftArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftRightTemplate: !!js/function &LongShiftRightTemplate >\n (lhs) => {\n return `${lhs} >>`;\n }\n LongShiftRightArgsTemplate: !!js/function &LongShiftRightArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongCompareTemplate: !!js/function &LongCompareTemplate >\n (lhs) => {\n return `${lhs} - `;\n }\n LongCompareArgsTemplate: !!js/function &LongCompareArgsTemplate >\n (lhs, arg) => {\n return arg;\n }\n LongIsOddTemplate: !!js/function &LongIsOddTemplate >\n (lhs) => {\n return `${lhs}`;\n }\n LongIsOddArgsTemplate: !!js/function &LongIsOddArgsTemplate >\n () => {\n return \' % 2 == 1\';\n }\n LongIsZeroTemplate: !!js/function &LongIsZeroTemplate >\n (lhs) => {\n return `${lhs} == 0`;\n }\n LongIsZeroArgsTemplate: !!js/function &LongIsZeroArgsTemplate >\n () => {\n return \'\';\n }\n LongIsNegativeTemplate: !!js/function &LongIsNegativeTemplate >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: !!js/function &LongIsNegativeArgsTemplate >\n () => {\n return \'\';\n }\n LongNegateTemplate: !!js/function &LongNegateTemplate >\n () => {\n return \'-\';\n }\n LongNegateArgsTemplate: !!js/function &LongNegateArgsTemplate >\n (lhs) => {\n return `${lhs}`;\n }\n LongNotTemplate: !!js/function &LongNotTemplate >\n () => {\n return \'~\';\n }\n LongNotArgsTemplate: !!js/function &LongNotArgsTemplate >\n (lhs) => {\n return `${lhs}`;\n }\n LongNotEqualsTemplate: !!js/function &LongNotEqualsTemplate >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: !!js/function &LongNotEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: !!js/function &LongGreaterThanTemplate >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: !!js/function &LongGreaterThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate:\n !!js/function &LongGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate:\n !!js/function &LongGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: !!js/function &LongLessThanTemplate >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: !!js/function &LongLessThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: !!js/function &LongLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate:\n !!js/function &LongLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: !!js/function &LongFloatApproxTemplate >\n (lhs) => {\n return `(float) ${lhs}`;\n }\n LongTopTemplate: !!js/function &LongTopTemplate >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: !!js/function &LongBottomTemplate >\n (lhs) => {\n return `${lhs} & 0x0000ffff`;\n }\n TimestampToStringTemplate: !!js/function &TimestampToStringTemplate >\n (lhs) => {\n return `${lhs}.ToString`;\n }\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n TimestampEqualsTemplate: !!js/function &TimestampEqualsTemplate >\n (lhs) => {\n return `${lhs}.Equals`;\n }\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate null\n TimestampGetLowBitsTemplate: !!js/function &TimestampGetLowBitsTemplate >\n (lhs) => {\n return `${lhs}.ToUniversalTime`;\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate null\n TimestampGetHighBitsTemplate: !!js/function &TimestampGetHighBitsTemplate >\n (lhs) => {\n return `${lhs}.Increment`;\n }\n TimestampGetHighBitsArgsTemplate:\n !!js/function &TimestampGetHighBitsArgsTemplate >\n (lhs) => {\n return \'\';\n }\n TimestampTTemplate: !!js/function &TimestampTTemplate >\n (lhs) => {\n return `${lhs}.ToUniversalTime()`;\n }\n TimestampITemplate: !!js/function &TimestampITemplate >\n (lhs) => {\n return `${lhs}.Increment`;\n }\n TimestampAsDateTemplate: !!js/function &TimestampAsDateTemplate >\n (lhs) => {\n return `new DateTime(1970, 1, 1).AddSeconds(${lhs}.Timestamp)`;\n }\n TimestampAsDateArgsTemplate: !!js/function &TimestampAsDateArgsTemplate >\n () => {\n return \'\';\n }\n TimestampCompareTemplate: !!js/function &TimestampCompareTemplate >\n (lhs) => {\n return `${lhs}.CompareTo`;\n }\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate null\n TimestampNotEqualsTemplate: !!js/function &TimestampNotEqualsTemplate >\n (lhs) => {\n return `${lhs} != `;\n }\n TimestampNotEqualsArgsTemplate:\n !!js/function &TimestampNotEqualsArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanTemplate: !!js/function &TimestampGreaterThanTemplate >\n (lhs) => {\n return `${lhs} > `;\n }\n TimestampGreaterThanArgsTemplate:\n !!js/function &TimestampGreaterThanArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanOrEqualTemplate:\n !!js/function &TimestampGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} >= `;\n }\n TimestampGreaterThanOrEqualArgsTemplate:\n !!js/function &TimestampGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanTemplate: !!js/function &TimestampLessThanTemplate >\n (lhs) => {\n return `${lhs} < `;\n }\n TimestampLessThanArgsTemplate: !!js/function &TimestampLessThanArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanOrEqualTemplate:\n !!js/function &TimestampLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} <= `;\n }\n TimestampLessThanOrEqualArgsTemplate:\n !!js/function &TimestampLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n SymbolValueOfTemplate: !!js/function &SymbolValueOfTemplate >\n (lhs) => {\n return `${lhs}`;\n }\n SymbolValueOfArgsTemplate: !!js/function &SymbolValueOfArgsTemplate >\n () => {\n return \'\';\n }\n SymbolInspectTemplate: !!js/function &SymbolInspectTemplate >\n (lhs) => {\n return `${lhs}`;\n }\n SymbolInspectArgsTemplate: !!js/function &SymbolInspectArgsTemplate >\n () => {\n return \'\';\n }\n SymbolToStringTemplate: !!js/function &SymbolToStringTemplate >\n (lhs) => {\n return `${lhs}`;\n }\n SymbolToStringArgsTemplate: !!js/function &SymbolToStringArgsTemplate >\n () => {\n return \'\';\n }\n # Symbol Templates\n CodeSymbolTemplate:\n !!js/function &CodeSymbolTemplate > # Also has process method\n () => {\n return \'BsonJavaScript\';\n }\n CodeSymbolArgsTemplate: !!js/function &CodeSymbolArgsTemplate >\n (lhs, code, scope) => {\n // Double quote stringify\n let newStr = code === undefined ? \'\' : code;\n const str = newStr;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n code = `"${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}"`;\n return (scope === undefined) ? `(${code})` : `WithScope(${code}, ${scope})`;\n }\n ObjectIdSymbolTemplate: !!js/function &ObjectIdSymbolTemplate >\n () => {\n return \'ObjectId\';\n }\n ObjectIdSymbolArgsTemplate: !!js/function &ObjectIdSymbolArgsTemplate >\n (lhs, str) => {\n if (!str || str.length === 0) {\n return \'()\';\n }\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `("${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}")`;\n }\n BinarySymbolTemplate: !!js/function &BinarySymbolTemplate >\n () => {\n return \'BsonBinaryData\';\n }\n BinarySymbolArgsTemplate: !!js/function &BinarySymbolArgsTemplate >\n (lhs, bytes, type) => {\n const str = bytes;\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n bytes = `"${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}"`;\n\n if (type === null) {\n return `(System.Text.Encoding.ASCII.GetBytes(${bytes}))`;\n }\n return `(System.Text.Encoding.ASCII.GetBytes(${bytes}), ${type})`;\n }\n BinarySymbolSubtypeDefaultTemplate:\n !!js/function &BinarySymbolSubtypeDefaultTemplate >\n () => {\n return \'BsonBinarySubType.Binary\';\n }\n BinarySymbolSubtypeFunctionTemplate:\n !!js/function &BinarySymbolSubtypeFunctionTemplate >\n () => {\n return \'BsonBinarySubType.Function\';\n }\n BinarySymbolSubtypeByteArrayTemplate:\n !!js/function &BinarySymbolSubtypeByteArrayTemplate >\n () => {\n return \'BsonBinarySubType.OldBinary\';\n }\n BinarySymbolSubtypeUuidOldTemplate:\n !!js/function &BinarySymbolSubtypeUuidOldTemplate >\n () => {\n return \'BsonBinarySubType.UuidLegacy\';\n }\n BinarySymbolSubtypeUuidTemplate:\n !!js/function &BinarySymbolSubtypeUuidTemplate >\n () => {\n return \'BsonBinarySubType.UuidStandard\';\n }\n BinarySymbolSubtypeMd5Template:\n !!js/function &BinarySymbolSubtypeMd5Template >\n () => {\n return \'BsonBinarySubType.MD5\';\n }\n BinarySymbolSubtypeUserDefinedTemplate:\n !!js/function &BinarySymbolSubtypeUserDefinedTemplate >\n () => {\n return \'BsonBinarySubType.UserDefined\';\n }\n DBRefSymbolTemplate: !!js/function &DBRefSymbolTemplate >\n () => {\n return \'MongoDBRef\';\n }\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null\n DoubleSymbolTemplate: !!js/function &DoubleSymbolTemplate >\n () => {\n return \'\';\n }\n DoubleSymbolArgsTemplate: !!js/function &DoubleSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n if (type === \'_hex\') {\n return `Convert.ToDouble(${arg})`;\n }\n if (type === \'_string\') {\n return `Convert.ToDouble(${arg})`;\n }\n\n if (type === \'_decimal\') {\n return arg;\n }\n\n return `${Math.round(arg).toFixed(1)}`;\n }\n Int32SymbolTemplate: !!js/function &Int32SymbolTemplate >\n () => {\n return \'\';\n }\n Int32SymbolArgsTemplate: !!js/function &Int32SymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n if (type === \'_hex\' || type === \'_decimal\' || type === \'_string\') {\n return `Convert.ToInt32(${arg})`;\n }\n\n return arg;\n }\n LongSymbolTemplate: !!js/function &LongSymbolTemplate >\n () => {\n return \'\';\n }\n LongSymbolArgsTemplate: !!js/function &LongSymbolArgsTemplate >\n (lhs, arg) => {\n if (!arg || arg.length === 0) {\n arg = \'0\';\n }\n if (arg.indexOf(\'\\\'\') === 0 || arg.indexOf(\'"\') === 0) {\n return `Convert.ToInt64(${arg})`;\n }\n return `${arg}L`;\n }\n LongSymbolMaxTemplate: !!js/function &LongSymbolMaxTemplate >\n () => {\n return \'Int64.MaxValue\';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: !!js/function &LongSymbolMinTemplate >\n () => {\n return \'Int64.MinValue\';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: !!js/function &LongSymbolZeroTemplate >\n (lhs) => {\n return \'0L\';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: !!js/function &LongSymbolOneTemplate >\n (lhs) => {\n return \'1L\';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: !!js/function &LongSymbolNegOneTemplate >\n (lhs) => {\n return \'-1L\';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate:\n !!js/function &LongSymbolFromBitsTemplate > # Also has process method\n () => {\n return \'\';\n }\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: !!js/function &LongSymbolFromIntTemplate >\n () => {\n return \'\';\n }\n LongSymbolFromIntArgsTemplate: !!js/function &LongSymbolFromIntArgsTemplate >\n (lhs, arg) => {\n return `${arg}L`;\n }\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate null\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: !!js/function &LongSymbolFromStringTemplate >\n () => {\n return \'Convert.ToInt64\';\n }\n LongSymbolFromStringArgsTemplate:\n !!js/function &LongSymbolFromStringArgsTemplate >\n (lhs, arg1, arg2) => {\n if (arg2) {\n return `(${arg1}, ${arg2})`\n }\n return `(${arg1}, 10)`\n }\n MinKeySymbolTemplate: !!js/function &MinKeySymbolTemplate >\n () => {\n return \'BsonMinKey\';\n }\n MinKeySymbolArgsTemplate: !!js/function &MinKeySymbolArgsTemplate >\n () => {\n return \'.Value\';\n }\n MaxKeySymbolTemplate: !!js/function &MaxKeySymbolTemplate >\n () => {\n return \'BsonMaxKey\';\n }\n MaxKeySymbolArgsTemplate: !!js/function &MaxKeySymbolArgsTemplate >\n () => {\n return \'.Value\';\n }\n TimestampSymbolTemplate: !!js/function &TimestampSymbolTemplate >\n () => {\n return \'BsonTimestamp\';\n }\n TimestampSymbolArgsTemplate: !!js/function &TimestampSymbolArgsTemplate >\n (lhs, arg1, arg2) => {\n if (typeof arg1 === \'undefined\') {\n return \'(0, 0)\'\n }\n return `(${arg1}, ${arg2})`;\n }\n SymbolSymbolTemplate: !!js/function &SymbolSymbolTemplate >\n () => {\n return \'\';\n }\n SymbolSymbolArgsTemplate: !!js/function &SymbolSymbolArgsTemplate >\n (_, arg) => {\n return arg; // no parens because generates as a string\n }\n BSONRegExpSymbolTemplate: !!js/function &BSONRegExpSymbolTemplate >\n () => {\n return \'BsonRegularExpression\';\n }\n BSONRegExpSymbolArgsTemplate: !!js/function &BSONRegExpSymbolArgsTemplate >\n (lhs, pattern, flags) => {\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `"${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}"`;\n }\n return `(${doubleStringify(pattern)}${flags ? \', \' + doubleStringify(flags) : \'\'})`;\n }\n Decimal128SymbolTemplate: !!js/function &Decimal128SymbolTemplate >\n () => {\n return \'Decimal128\';\n }\n Decimal128SymbolArgsTemplate: !!js/function &Decimal128SymbolArgsTemplate >\n (_, str) => { // just stringify\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `.Parse("${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}")`;\n }\n Decimal128SymbolFromStringTemplate:\n !!js/function &Decimal128SymbolFromStringTemplate >\n (lhs) => {\n return `${lhs}.Parse`;\n }\n Decimal128SymbolFromStringArgsTemplate:\n !!js/function &Decimal128SymbolFromStringArgsTemplate >\n (lhs, arg) => {\n return `(${arg})`;\n }\n Decimal128ToStringTemplate: !!js/function &Decimal128ToStringTemplate >\n (lhs) => {\n return `${lhs}.ToString`;\n }\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # BSON Util Templates\n ObjectIdCreateFromHexStringTemplate:\n !!js/function &ObjectIdCreateFromHexStringTemplate >\n (lhs) => {\n return `new ${lhs}`;\n }\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate null\n ObjectIdCreateFromTimeTemplate:\n !!js/function &ObjectIdCreateFromTimeTemplate >\n () => {\n return `new ObjectId.GenerateNewId`;\n }\n ObjectIdCreateFromTimeArgsTemplate:\n !!js/function &ObjectIdCreateFromTimeArgsTemplate >\n (lhs, arg, isNumber) => {\n if (isNumber) {\n return `(Convert.ToInt32(${arg}))`;\n }\n return `(${arg})`;\n }\n ObjectIdIsValidTemplate: !!js/function &ObjectIdIsValidTemplate >\n (lhs) => {\n return `new ${lhs}`;\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n # JS Symbol Templates\n NumberSymbolTemplate: !!js/function &NumberSymbolTemplate >\n () => {\n return \'\';\n }\n NumberSymbolArgsTemplate: !!js/function &NumberSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n if (type === \'_string\') {\n if (arg.indexOf(\'.\') !== -1) {\n return `float.Parse(${arg})`\n }\n return `int.Parse(${arg})`;\n }\n\n if (arg.indexOf(\'.\') !== -1) {\n return `(float) ${arg}`\n }\n return `(int) ${arg}`;\n }\n DateSymbolTemplate: !!js/function &DateSymbolTemplate >\n () => {\n return \'DateTime\';\n }\n DateSymbolArgsTemplate: !!js/function &DateSymbolArgsTemplate >\n (lhs, date, isString) => {\n let toStr = isString? \'.ToString("ddd MMM dd yyyy HH\\\':\\\'mm\\\':\\\'ss UTC")\' : \'\';\n\n if (date === null) {\n return `${lhs}.Now${toStr}`;\n }\n\n const dateStr = [\n date.getUTCFullYear(),\n date.getUTCMonth() + 1,\n date.getUTCDate(),\n date.getUTCHours(),\n date.getUTCMinutes(),\n date.getUTCSeconds()\n ].join(\', \');\n\n return `new ${lhs}(${dateStr})${toStr}`;\n }\n DateSymbolNowTemplate: !!js/function &DateSymbolNowTemplate >\n () => {\n return \'DateTime.Now\';\n }\n DateSymbolNowArgsTemplate: !!js/function &DateSymbolNowArgsTemplate >\n () => {\n return \'\';\n }\n RegExpSymbolTemplate:\n !!js/function &RegExpSymbolTemplate > # Also has process method\n () => {\n return \'Regex\';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null\n ImportTemplate: !!js/function &ImportTemplate >\n (args) => {\n const universal = [\'using MongoDB.Bson;\', \'using MongoDB.Driver;\'];\n const all = universal.concat(Object.values(args));\n return all.join(\'\\n\');\n }\n DriverImportTemplate: &DriverImportTemplate null\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: !!js/function &8ImportTemplate >\n () => {\n return \'using System.Text.RegularExpressions;\';\n }\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: &100ImportTemplate null\n 101ImportTemplate: &101ImportTemplate null\n 102ImportTemplate: &102ImportTemplate null\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n 107ImportTemplate: &107ImportTemplate null\n 108ImportTemplate: &108ImportTemplate null\n 109ImportTemplate: &109ImportTemplate null\n 110ImportTemplate: &110ImportTemplate null\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: &112ImportTemplate null\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: !!js/function &200ImportTemplate >\n () => {\n return \'using System;\';\n }\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven\'t implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: "_bool"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: "_integer"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: "_long"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: "_decimal"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: "_hex"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: "_octal"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: "_numeric"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: "_string"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: "_regex"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: "_array"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: "_object"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: "_null"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: "_undefined"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn\'t add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren\'t defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: "Code"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: "code"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: "scope"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: "ObjectId"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: "equals"\n args:\n - [ "ObjectId" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: "getTimestamp"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: "BinData"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: "base64"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: "length"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: "subtype"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: "DBRef"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: "getDb"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: "$db"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: "getCollection"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: "getRef"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: "$ref"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: "getId"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: "$id"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: "NumberInt"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: "NumberLong"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "LongtoString" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: "equals"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: "toInt"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: "toNumber"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: "compare"\n args:\n - [ "Long" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: "isOdd"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: "isZero"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: "isNegative"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: "negate"\n type: "Long"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: "not"\n type: "Long"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: "notEquals"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: "greaterThan"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: "greaterThanOrEqual"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: "lessThan"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: "lessThanOrEqual"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: "add"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: "subtract"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: "multiply"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: "div"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: "modulo"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: "and"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: "or"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: "xor"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: "shiftLeft"\n args:\n - [ *IntegerType ]\n type: "Long"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: "shiftRight"\n args:\n - [ *IntegerType ]\n type: "Long"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: "MinKey"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: "MaxKey"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: "Timestamp"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: "equals"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: "getLowBits"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: "getHighBits"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: "compare"\n args:\n - [ "Timestamp" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: "notEquals"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: "greaterThan"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: "greaterThanOrEqual"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: "lessThan"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: "lessThanOrEqual"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: "BSONSymbol"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: "valueOf"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: "inspect"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: "Double"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: "Decimal128"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: "NumberDecimal"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: "SUBTYPE_DEFAULT"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: "SUBTYPE_FUNCTION"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: "SUBTYPE_BYTE_ARRAY"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: "SUBTYPE_UUID_OLD"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: "SUBTYPE_UUID"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: "SUBTYPE_MD5"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: "SUBTYPE_USER_DEFINED"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: "BSONRegExp"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: "Date"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: "RegExp"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: "Code"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: "ObjectId"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: "createFromHexString"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: "ObjectIdCreateFromTime"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: "isValid"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: "BinData"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: "DBRef"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: "Int32"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: "NumberLong"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: "MinKey"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: "MaxKey"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: "Timestamp"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: "Symbol"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: "NumberDecimal"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: "BSONRegExp"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: "BSONSymbol"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: "Decimal128"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: "fromString"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: "Double"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: "Int32"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: "Long"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: "MAX_VALUE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: "MIN_VALUE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: "ZERO"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: "ONE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: "NEG_ONE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: "LongfromBits" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: "fromInt"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: "fromNumber"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: "fromString"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: "Number"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: "Date"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: "now"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: "ISODate"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: "now"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: "RegExp"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n'; diff --git a/packages/bson-transpilers/lib/symbol-table/shelltogo.js b/packages/bson-transpilers/lib/symbol-table/shelltogo.js index 2c8d4243a79..fb45ce66fc0 100644 --- a/packages/bson-transpilers/lib/symbol-table/shelltogo.js +++ b/packages/bson-transpilers/lib/symbol-table/shelltogo.js @@ -1 +1,2 @@ -module.exports="SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace 'null' with '!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'u'\n y: 'y'\n g: 'g'\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: &DriverTemplate !!js/function >\n (spec) => {\n const options = spec.options;\n const uri = spec.options.uri\n const filter = spec.filter || {};\n const exportMode = spec.exportMode;\n delete spec.options;\n delete spec.filter;\n delete spec.exportMode;\n\n const indent = (depth) => ' '.repeat(depth)\n\n let driverMethod;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'DeleteMany';\n break;\n case 'Update Query':\n driverMethod = 'UpdateMany';\n break;\n default:\n driverMethod = 'Find';\n }\n\n const comment = []\n .concat('// Requires the MongoDB Go Driver')\n .concat('// https://go.mongodb.org/mongo-driver')\n .join('\\n');\n\n const connect = []\n .concat('ctx := context.TODO()')\n .concat(this.declarations.length() > 0 ? `\\n${this.declarations.toString()}\\n` : '')\n .concat('// Set client options')\n .concat(`clientOptions := options.Client().ApplyURI(\"${uri}\")`)\n .concat('')\n .concat('// Connect to MongoDB')\n .concat('client, err := mongo.Connect(ctx, clientOptions)')\n .concat('if err != nil {')\n .concat(' log.Fatal(err)')\n .concat('}')\n .concat('defer func() {')\n .concat(' if err := client.Disconnect(ctx); err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat('}()')\n .join('\\n');\n\n const coll = []\n .concat(`coll := client.Database(\"${options.database}\").Collection(\"${options.collection}\")`)\n .join('\\n');\n\n if ('aggregation' in spec) {\n return []\n .concat(comment)\n .concat(connect)\n .concat('')\n .concat('// Open an aggregation cursor')\n .concat(`${coll}`)\n .concat(`_, err = coll.Aggregate(ctx, ${spec.aggregation})`)\n .concat('if err != nil {')\n .concat(' log.Fatal(err)')\n .concat('}')\n .join('\\n');\n }\n\n const findOptions = []\n if (spec.project)\n findOptions.push(`options.Find().SetProjection(${spec.project})`);\n if (spec.sort)\n findOptions.push(`options.Find().SetSort(${spec.sort})`);\n\n const optsStr = findOptions.length > 0 ? `,\\n${indent(1)}${findOptions.join(`,\\n${indent(1)}`)}` : ''\n\n return []\n .concat(comment)\n .concat(connect)\n .concat('')\n .concat(`${coll}`)\n .concat(`_, err = coll.${driverMethod}(ctx, ${filter}${optsStr})`)\n .concat('if err != nil {')\n .concat(' log.Fatal(err)')\n .concat('}')\n .join('\\n');\n }\n EqualitySyntaxTemplate: &EqualitySyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n }\n else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: &InSyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n this.declarations.addFunc([]\n .concat(`var contains = func(elems bson.A, v interface{}) bool {`)\n .concat(' for _, s := range elems {')\n .concat(' if v == s {')\n .concat(' return true')\n .concat(' }')\n .concat(' }')\n .concat(' return false')\n .concat('}')\n .join('\\n'));\n let prefix = '';\n if (op.includes('!') || op.includes('not'))\n prefix = '!';\n return `${prefix}contains(${rhs}, ${lhs})`;\n }\n AndSyntaxTemplate: &AndSyntaxTemplate !!js/function >\n (args) => args.join(' && ')\n OrSyntaxTemplate: &OrSyntaxTemplate !!js/function >\n (args) => args.join(' || ')\n NotSyntaxTemplate: &NotSyntaxTemplate !!js/function >\n (arg) => `!${arg}`\n UnarySyntaxTemplate: &UnarySyntaxTemplate !!js/function >\n (op, val) => {\n switch(op) {\n case '+':\n return val;\n case '~':\n return `!${val}`;\n default:\n return `${op}${val}`;\n }\n return `${op}${val}`;\n }\n BinarySyntaxTemplate: &BinarySyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `${s} / ${rhs}`\n case '**':\n return `math.Pow(${s}, ${rhs})`\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosTemplate: &EosSyntaxTemplate null # No args. End-of-line\n EofTemplate: &EofSyntaxTemplate null # No args. End-of-file\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: &StringTypeTemplate !!js/function >\n (str) => {\n // Double quote stringify\n const singleQuoted = str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'';\n const doubleQuoted = str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n str = str.substr(1, str.length - 2);\n return `\"${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n RegexTypeTemplate: &RegexTypeTemplate !!js/function >\n (pattern, flags) => {\n // Wrap string in double quotes\n const doubleStringify = (str) => {\n const singleQuoted = str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'';\n const doubleQuoted = str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n str = str.substr(1, str.length - 2);\n return `\"${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n\n const structParts = [];\n structParts.push(`Pattern: ${doubleStringify(pattern)}`);\n if (flags)\n structParts.push(`Options: ${doubleStringify(flags)}`);\n return `primitive.Regex{${structParts.join(\", \")}}`;\n }\n BoolTypeTemplate: &BoolTypeTemplate !!js/function >\n (literal) => literal.toLowerCase()\n IntegerTypeTemplate: &IntegerTypeTemplate null # args: literal, argType (i.e. '_string', '_decimal' etc)\n DecimalTypeTemplate: &DecimalTypeTemplate null # args: literal, argType\n LongBasicTypeTemplate: &LongBasicTypeTemplate null # args: literal, argType\n HexTypeTemplate: &HexTypeTemplate null # args: literal, argType\n OctalTypeTemplate: &OctalTypeTemplate null # args: literal, argType\n NumericTypeTemplate: &NumericTypeTemplate null # args: literal, argType\n ArrayTypeTemplate: &ArrayTypeTemplate !!js/function >\n (literal, depth) => {\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n if (literal === '')\n return 'bson.A{}';\n return `bson.A{${literal}${closingIndent}}`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate !!js/function >\n (arg, depth, last) => {\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n return `${indent}${arg},`;\n }\n NullTypeTemplate: &NullTypeTemplate !!js/function >\n () => 'primitive.Null{}'\n UndefinedTypeTemplate: &UndefinedTypeTemplate !!js/function >\n () => 'primitive.Undefined{}'\n ObjectTypeTemplate: &ObjectTypeTemplate !!js/function >\n (literal) => `bson.D{${literal}}`\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate !!js/function >\n (args, depth) => {\n // If there are no args, then there is nothing for us to format\n if (args.length === 0)\n return '';\n\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n\n // Indent every line of a string\n const indentBlock = (string, count = 1, options = {}) => {\n const {\n indent = ' ',\n includeEmptyLines = false\n } = options;\n\n const regex = includeEmptyLines ? /^/gm : /^(?!\\s*$)/gm;\n return string.replace(regex, indent.repeat(count));\n }\n\n // Wrap string in double quotes\n const doubleStringify = (str) => {\n const singleQuoted = str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'';\n const doubleQuoted = str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n str = str.substr(1, str.length - 2);\n return `\"${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n\n // Check if a string is multiple lines i.e. has a break point\n const isMultiline = (element) => /\\r|\\n/.exec(element)\n\n // Format element by go type\n const fmt = (element) => {\n const hash = { multiline: isMultiline(element) };\n const typeFormatters = {\n 'bson.A': (el, hash) => isMultiline(el) ? indentBlock(`${indent}${el},${indent}`) : ` ${el}`,\n 'bson.D': (el, hash) => isMultiline(el) ? indentBlock(`${indent}${el},${indent}`) : ` ${el}`,\n default: (el, hash) => isMultiline(el) ? el : ` ${el}`\n };\n hash.el = typeFormatters.default(element);\n for (const type in typeFormatters)\n if (element.startsWith(type)) {\n hash.el = typeFormatters[type](element);\n break;\n }\n return hash;\n }\n\n // Get the {key, value} pair for the bson.D object\n const getPairs = (args, sep = `,${indent}`) => {\n const hash = { multiline: false }\n hash.el = args.map((pair) => {\n const fmtPair = fmt(pair[1])\n if (!hash.multiline && fmtPair.multiline)\n hash.multiline = true\n return `{${doubleStringify(pair[0])},${fmtPair.el}}`\n }).join(sep)\n return hash\n }\n\n const pairs = getPairs(args);\n const singleLine = args.length <= 1 && !pairs.multiline;\n const prefix = singleLine ? '' : indent;\n const suffix = singleLine ? '' : ',' + closingIndent;\n return `${prefix}${pairs.el}${suffix}`;\n }\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don't take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: &CodeSymbolTemplate !!js/function >\n () => 'primitive.CodeWithScope'\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate !!js/function >\n (_, code, scope) => {\n if (code === undefined)\n return `{}`;\n\n if (scope !== undefined)\n scope = `Scope: ${scope}`;\n\n const singleQuoted = code.charAt(0) === '\\'' && code.charAt(code.length - 1) === '\\'';\n const doubleQuoted = code.charAt(0) === '\"' && code.charAt(code.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n code = code.substr(1, code.length - 2);\n\n code = `Code: primitive.JavaScript(\"${code.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n return (scope === undefined) ? `{${code}}` : `{${code}, ${scope}}`;\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate !!js/function >\n () => ''\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate !!js/function >\n (_, arg) => {\n if (arg === undefined || arg === '')\n return 'primitive.NewObjectID()';\n\n // Double quote stringify\n const singleQuoted = arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'';\n const doubleQuoted = arg.charAt(0) === '\"' && arg.charAt(arg.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n arg = arg.substr(1, arg.length - 2);\n arg = `\"${arg.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n this.declarations.addFunc([]\n .concat('var objectIDFromHex = func(hex string) primitive.ObjectID {')\n .concat(` objectID, err := primitive.ObjectIDFromHex(hex)`)\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return objectID')\n .concat('}')\n .join('\\n'));\n return `objectIDFromHex(${arg})`\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate null\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate null\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate null\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate null\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate null\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate null\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template null\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate null\n DBRefSymbolTemplate: &DBRefSymbolTemplate null # No args\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null\n DoubleSymbolTemplate: &DoubleSymbolTemplate !!js/function >\n () => ''\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n if (!arg)\n arg = 0;\n switch(type) {\n case '_string':\n this.declarations.addFunc([]\n .concat('var parseFloat64 = func(str string) float64 {')\n .concat(' f64, err := strconv.ParseFloat(str, 64)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return f64')\n .concat('}')\n .join('\\n'));\n return `parseFloat64(${arg})`\n default:\n return `float64(${arg})`;\n }\n }\n Int32SymbolTemplate: &Int32SymbolTemplate !!js/function >\n () => ''\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n if (!arg)\n arg = 0\n switch(type) {\n case '_string':\n this.declarations.addFunc([]\n .concat('var parseInt32 = func(str string) int32 {')\n .concat('i64, err := strconv.ParseInt(str, 10, 32)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return int32(i64)')\n .concat('}')\n .join('\\n'));\n return `parseInt32(${arg})`;\n default:\n return `int32(${arg})`;\n }\n }\n LongSymbolTemplate: &LongSymbolTemplate !!js/function >\n () => ''\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n if (!arg)\n arg = 0\n switch(type) {\n case '_string':\n this.declarations.addFunc([]\n .concat('var parseInt = func(str string) int64 {')\n .concat(' i64, err := strconv.ParseInt(str, 10, 64)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return i64')\n .concat('}')\n .join('\\n'));\n return `parseInt64(${arg})`;\n default:\n return `int64(${arg})`;\n }\n }\n RegExpSymbolTemplate: &RegExpSymbolTemplate !!js/function >\n () => 'regex'\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: &SymbolSymbolTemplate !!js/function >\n () => 'primitive.Symbol'\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate null\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate !!js/function >\n () => 'primitive.Regex'\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate !!js/function >\n (_, pattern, flags) => {\n // Wrap string in double quotes\n const doubleStringify = (str) => {\n const singleQuoted = str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'';\n const doubleQuoted = str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n str = str.substr(1, str.length - 2);\n return `\"${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n\n const structParts = [];\n structParts.push(`Pattern: ${doubleStringify(pattern)}`);\n if (flags)\n structParts.push(`Options: ${doubleStringify(flags)}`);\n return `(${structParts.join(\", \")})`;\n }\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate !!js/function >\n () => ''\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate !!js/function >\n (_, arg) => {\n if (!arg)\n arg = '\"0\"';\n\n // Double quote stringify\n const singleQuoted = arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'';\n const doubleQuoted = arg.charAt(0) === '\"' && arg.charAt(arg.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n arg = arg.substr(1, arg.length - 2);\n arg = `\"${arg.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n\n this.declarations.addFunc([]\n .concat('var parseDecimal128 = func(str string) primitive.Decimal128 {')\n .concat(' d128, err := primitive.ParseDecimal128(str)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return d128')\n .concat('}')\n .join('\\n'));\n return `parseDecimal128(${arg})`;\n }\n MinKeySymbolTemplate: &MinKeySymbolTemplate !!js/function >\n () => 'primitive.MinKey'\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate !!js/function >\n () => '{}'\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate !!js/function >\n () => 'primitive.MaxKey'\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate !!js/function >\n () => '{}'\n TimestampSymbolTemplate: &TimestampSymbolTemplate !!js/function >\n () => 'primitive.Timestamp'\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate !!js/function >\n (lhs, low, high) => {\n if (low === undefined) {\n low = 0;\n high = 0;\n }\n return `{T: ${low}, I: ${high}}`\n }\n # non bson-specific\n NumberSymbolTemplate: &NumberSymbolTemplate !!js/function >\n () => ''\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n switch(type) {\n case '_string':\n if (arg.indexOf('.') !== -1) {\n this.declarations.addFunc([]\n .concat('var parseFloat64 = func(str string) float64 {')\n .concat(' f64, err := strconv.ParseFloat(str, 64)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return f64')\n .concat('}')\n .join('\\n'));\n return `parseFloat64(${arg})`\n }\n this.declarations.addFunc([]\n .concat('var parseInt = func(str string) int64 {')\n .concat(' i64, err := strconv.ParseInt(str, 10, 64)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return i64')\n .concat('}')\n .join('\\n'));\n return `parseInt64(${arg})`;\n default:\n return `${arg}`\n }\n }\n DateSymbolTemplate: &DateSymbolTemplate !!js/function >\n () => 'time.Date'\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate !!js/function >\n (lhs, date, isString) => {\n if (date === null)\n return `time.Now()`;\n\n const dateStr = [\n date.getUTCFullYear(),\n date.getUTCMonth() + 1,\n date.getUTCDate(),\n date.getUTCHours(),\n date.getUTCMinutes(),\n date.getUTCSeconds(),\n '0',\n 'time.UTC'\n ].join(', ');\n\n return `${lhs}(${dateStr})`\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These're variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: &CodeCodeTemplate !!js/function >\n (lhs) => `${lhs}.Code`\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate !!js/function >\n (lhs) => lhs\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate !!js/function >\n (lhs) => `${lhs}.String()`\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate !!js/function >\n () => ''\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate !!js/function >\n () => ''\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate !!js/function >\n (arg1, arg2) => `${arg1} == ${arg2}`\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate !!js/function >\n (lhs) => `${lhs}.Timestamp()`\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate !!js/function >\n () => ''\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate !!js/function >\n () => `primitive.IsValidObjectID`\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate null\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: &BinarySubtypeTemplate null\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate null\n DBRefGetDBTemplate: &DBRefGetDBTemplate null\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate null\n DBRefGetIdTemplate: &DBRefGetIdTemplate null\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate null\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate null\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate null\n DBRefToStringTemplate: &DBRefToStringTemplate null\n DBRefToStringArgsTemplate: &DBRefToStringArgsTemplate null\n DoubleValueOfTemplate: &DoubleValueOfTemplate null\n DoubleValueOfArgsTemplate: &DoubleValueOfArgsTemplate null\n Int32ValueOfTemplate: &Int32ValueOfTemplate null\n Int32ValueOfArgsTemplate: &Int32ValueOfArgsTemplate null\n Int32ToStringTemplate: &Int32ToStringTemplate null\n Int32ToStringArgsTemplate: &Int32ToStringArgsTemplate null\n LongEqualsTemplate: &LongEqualsTemplate !!js/function >\n (lhs) => `${lhs} == `\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate !!js/function >\n (_, arg) => arg\n LongToStringTemplate: &LongToStringTemplate !!js/function >\n (lhs) => `strconv.Itoa(${lhs})`\n LongToStringArgsTemplate: &LongToStringArgsTemplate !!js/function >\n () => ''\n LongToIntTemplate: &LongToIntTemplate !!js/function >\n (lhs) => `int(${lhs})`\n LongToIntArgsTemplate: &LongToIntArgsTemplate !!js/function >\n () => ''\n LongValueOfTemplate: &LongValueOfTemplate null\n LongValueOfArgsTemplate: &LongValueOfArgsTemplate null\n LongToNumberTemplate: &LongToNumberTemplate !!js/function >\n (lhs) => `float64(${lhs})`\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate !!js/function >\n (arg) => ''\n LongAddTemplate: &LongAddTemplate !!js/function >\n (lhs) => `${lhs} + `\n LongAddArgsTemplate: &LongAddArgsTemplate !!js/function >\n (_, args) => args\n LongSubtractTemplate: &LongSubtractTemplate !!js/function >\n (lhs) => `${lhs} - `\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate !!js/function >\n (_, arg) => arg\n LongMultiplyTemplate: &LongMultiplyTemplate !!js/function >\n (lhs) => `${lhs} * `\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate !!js/function >\n (_, arg) => arg\n LongDivTemplate: &LongDivTemplate !!js/function >\n (lhs) => `${lhs} / `\n LongDivArgsTemplate: &LongDivArgsTemplate !!js/function >\n (_, arg) => arg\n LongModuloTemplate: &LongModuloTemplate !!js/function >\n (lhs) => `${lhs} % `\n LongModuloArgsTemplate: &LongModuloArgsTemplate !!js/function >\n (_, arg) => arg\n LongAndTemplate: &LongAndTemplate !!js/function >\n (lhs) => `${lhs} & `\n LongAndArgsTemplate: &LongAndArgsTemplate !!js/function >\n (_, arg) => arg\n LongOrTemplate: &LongOrTemplate !!js/function >\n (lhs) => `${lhs} | `\n LongOrArgsTemplate: &LongOrArgsTemplate !!js/function >\n (_, arg) => arg\n LongXorTemplate: &LongXorTemplate !!js/function >\n (lhs) => `${lhs} ^ `\n LongXorArgsTemplate: &LongXorArgsTemplate !!js/function >\n (_, arg) => arg\n LongShiftLeftTemplate: &LongShiftLeftTemplate !!js/function >\n (lhs) => `${lhs} << `\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongShiftRightTemplate: &LongShiftRightTemplate !!js/function >\n (lhs) => `${lhs} >> `\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongCompareTemplate: &LongCompareTemplate !!js/function >\n (lhs) => `${lhs} - `\n LongCompareArgsTemplate: &LongCompareArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongIsOddTemplate: &LongIsOddTemplate !!js/function >\n (arg) => `${arg} % 2 == 1`\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate !!js/function >\n () => ''\n LongIsZeroTemplate: &LongIsZeroTemplate !!js/function >\n (arg) => `${arg} == int64(0)`\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate !!js/function >\n () => ''\n LongIsNegativeTemplate: &LongIsNegativeTemplate !!js/function >\n (arg) => `${arg} < int64(0)`\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate !!js/function >\n () => ''\n LongNegateTemplate: &LongNegateTemplate !!js/function >\n () => '-'\n LongNegateArgsTemplate: &LongNegateArgsTemplate !!js/function >\n (lhs) => lhs\n LongNotTemplate: &LongNotTemplate !!js/function >\n () => '^'\n LongNotArgsTemplate: &LongNotArgsTemplate !!js/function >\n (lhs) => lhs\n LongNotEqualsTemplate: &LongNotEqualsTemplate !!js/function >\n (lhs) => `${lhs} != `\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongGreaterThanTemplate: &LongGreaterThanTemplate !!js/function >\n (lhs) => `${lhs} > `\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate !!js/function >\n (lhs) => `${lhs} >= `\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongLessThanTemplate: &LongLessThanTemplate !!js/function >\n (lhs) => `${lhs} < `\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate !!js/function >\n (lhs) => `${lhs} <= `\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongFloatApproxTemplate: &LongFloatApproxTemplate !!js/function >\n (arg) => `float64(${arg})`\n LongTopTemplate: &LongTopTemplate !!js/function >\n (arg) => `${arg} >> 32`\n LongBottomTemplate: &LongBottomTemplate !!js/function >\n (arg) => `${arg} & 0x0000ffff`\n TimestampToStringTemplate: &TimestampToStringTemplate !!js/function >\n (lhs) => `time.Unix(${lhs}.T, 0).String`\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n () => '()'\n TimestampEqualsTemplate: &TimestampEqualsTemplate !!js/function >\n (lhs) => `${lhs}.Equal`\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate !!js/function >\n (_, rhs) => `(${rhs})`\n TimestampGetLowBitsTemplate: &TimestampGetLowBitsTemplate !!js/function >\n (lhs) => `${lhs}.T`\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate !!js/function >\n () => ''\n TimestampGetHighBitsTemplate: &TimestampGetHighBitsTemplate !!js/function >\n (lhs) => `${lhs}.I`\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate !!js/function >\n () => ''\n TimestampTTemplate: &TimestampTTemplate !!js/function >\n (lhs) => `${lhs}.T`\n TimestampITemplate: &TimestampITemplate !!js/function >\n (lhs) => `${lhs}.I`\n TimestampAsDateTemplate: &TimestampAsDateTemplate !!js/function >\n (lhs) => `time.Unix(${lhs}.T, 0)`\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate !!js/function >\n () => ''\n TimestampCompareTemplate: &TimestampCompareTemplate !!js/function >\n () => 'primitive.CompareTimestamp'\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate !!js/function >\n (lhs, rhs) => `(${lhs}, ${rhs})`\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate !!js/function >\n (lhs) => `!${lhs}.Equal`\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate !!js/function >\n (_, rhs) => `(${rhs})`\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate !!js/function >\n () => ''\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate !!js/function >\n (lhs, rhs) => `primitive.CompareTimestamp(${lhs}, ${rhs}) == 1`\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate !!js/function >\n () => ''\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate !!js/function >\n (arg1, arg2) => `primitive.CompareTimestamp(${arg1}, ${arg2}) >= 0`\n TimestampLessThanTemplate: &TimestampLessThanTemplate !!js/function >\n (lhs) => ''\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate !!js/function >\n (lhs, rhs) => `primitive.CompareTimestamp(${lhs}, ${rhs}) == -1`\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate !!js/function >\n () => ''\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate !!js/function >\n (arg1, arg2) => `primitive.CompareTimestamp(${arg1}, ${arg2}) <= 0`\n SymbolValueOfTemplate: &SymbolValueOfTemplate !!js/function >\n () => ''\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate !!js/function >\n (arg) => arg\n SymbolInspectTemplate: &SymbolInspectTemplate !!js/function >\n () => ''\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate !!js/function >\n (arg) => arg\n SymbolToStringTemplate: &SymbolToStringTemplate !!js/function >\n () => ''\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate !!js/function >\n (lhs) => `string(${lhs})`\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate !!js/function >\n (lhs) => `${lhs}.String()`\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate !!js/function >\n () => ''\n # non bson-specific\n DateSymbolNowTemplate: &DateSymbolNowTemplate !!js/function >\n () => 'time.Now()'\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate !!js/function >\n () => ''\n\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These're variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don't overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate !!js/function >\n () => 'int(^uint(0) >> 1)'\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate !!js/function >\n () => '-(1+int(^uint(0) >> 1))'\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate !!js/function >\n () => 'int64(0)'\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate !!js/function >\n () => 'int64(1)'\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate !!js/function >\n () => 'int64(-1)'\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate !!js/function >\n () => 'int64'\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate !!js/function >\n () => 'int64'\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate null\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate !!js/function >\n () => 'int64'\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate !!js/function >\n () => ''\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate !!js/function >\n (_, arg) => {\n this.declarations.addFunc([]\n .concat('var int64FromString = func(str string) int64 {')\n .concat(' f64, err := strconv.Atoi(str)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return f64')\n .concat('}')\n .join('\\n'));\n return `int64FromString(${arg})`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate !!js/function >\n () => ''\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate !!js/function >\n (_, arg) => {\n this.declarations.addFunc([]\n .concat('var parseDecimal128 = func(str string) primitive.Decimal128 {')\n .concat(' d128, err := primitive.ParseDecimal128(str)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return d128')\n .concat('}')\n .join('\\n'));\n return `parseDecimal128(${arg})`;\n }\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate !!js/function >\n () => ''\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate !!js/function >\n (_, arg) => {\n this.declarations.addFunc([]\n .concat('var objectIDFromHex = func(hex string) primitive.ObjectID {')\n .concat(` objectID, err := primitive.ObjectIDFromHex(hex)`)\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return objectID')\n .concat('}')\n .join('\\n'));\n return `objectIDFromHex(${arg})`\n }\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate !!js/function >\n () => 'primitive.NewObjectIDFromTimestamp'\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate !!js/function >\n (_, arg, isNumber) => isNumber ? `(time.Unix(${arg}, int64(0)))` : `(${arg})`\n # non bson-specific would go here, but there aren't any atm.\n\n #############################################\n # Imports #\n # #\n # Each type has a 'code' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: &ImportTemplate !!js/function >\n (args) => {\n const imports = Object.values(args).flat()\n const driverImports = args.driver || [];\n delete args['driver'];\n\n const flattenedArgs = Array.from(new Set([...driverImports, ...imports])).sort();\n const universal = [];\n const all = universal\n .concat(flattenedArgs)\n .map((i) => ` \"${i}\"`);\n return []\n .concat('import (')\n .concat(all.join('\\n'))\n .concat(')')\n .join('\\n');\n }\n DriverImportTemplate: &DriverImportTemplate !!js/function >\n () => {\n return [\n \"go.mongodb.org/mongo-driver/mongo\",\n \"go.mongodb.org/mongo-driver/mongo/options\",\n \"context\",\n \"log\"\n ]\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate !!js/function >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate !!js/function >\n () => ['go.mongodb.org/mongo-driver/bson']\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: &100ImportTemplate !!js/function >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 101ImportTemplate: &101ImportTemplate !!js/function >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive', 'log']\n 102ImportTemplate: &102ImportTemplate null\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: &104ImportTemplate !!js/function >\n (args) => ['log', 'strconv']\n 105ImportTemplate: &105ImportTemplate !!js/function >\n (args) => ['log', 'strconv']\n 106ImportTemplate: &106ImportTemplate !!js/function >\n (args) => ['log', 'strconv']\n 107ImportTemplate: &107ImportTemplate !!js/function >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 108ImportTemplate: &108ImportTemplate !!js/function >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 109ImportTemplate: &109ImportTemplate !!js/function >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 110ImportTemplate: &110ImportTemplate !!js/function >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 111ImportTemplate: &111ImportTemplate !!js/function >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 112ImportTemplate: &112ImportTemplate !!js/function >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive', 'log']\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate !!js/function >\n (args) => ['time.Time']\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; +module.exports = + "SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace 'null' with '!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'u'\n y: 'y'\n g: 'g'\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: !!js/function &DriverTemplate >\n (spec) => {\n const options = spec.options;\n const uri = spec.options.uri\n const filter = spec.filter || {};\n const exportMode = spec.exportMode;\n delete spec.options;\n delete spec.filter;\n delete spec.exportMode;\n\n const indent = (depth) => ' '.repeat(depth)\n\n let driverMethod;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'DeleteMany';\n break;\n case 'Update Query':\n driverMethod = 'UpdateMany';\n break;\n default:\n driverMethod = 'Find';\n }\n\n const comment = []\n .concat('// Requires the MongoDB Go Driver')\n .concat('// https://go.mongodb.org/mongo-driver')\n .join('\\n');\n\n const connect = []\n .concat('ctx := context.TODO()')\n .concat(this.declarations.length() > 0 ? `\\n${this.declarations.toString()}\\n` : '')\n .concat('// Set client options')\n .concat(`clientOptions := options.Client().ApplyURI(\"${uri}\")`)\n .concat('')\n .concat('// Connect to MongoDB')\n .concat('client, err := mongo.Connect(ctx, clientOptions)')\n .concat('if err != nil {')\n .concat(' log.Fatal(err)')\n .concat('}')\n .concat('defer func() {')\n .concat(' if err := client.Disconnect(ctx); err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat('}()')\n .join('\\n');\n\n const coll = []\n .concat(`coll := client.Database(\"${options.database}\").Collection(\"${options.collection}\")`)\n .join('\\n');\n\n if ('aggregation' in spec) {\n return []\n .concat(comment)\n .concat(connect)\n .concat('')\n .concat('// Open an aggregation cursor')\n .concat(`${coll}`)\n .concat(`_, err = coll.Aggregate(ctx, ${spec.aggregation})`)\n .concat('if err != nil {')\n .concat(' log.Fatal(err)')\n .concat('}')\n .join('\\n');\n }\n\n const findOptions = []\n if (spec.project)\n findOptions.push(`options.Find().SetProjection(${spec.project})`);\n if (spec.sort)\n findOptions.push(`options.Find().SetSort(${spec.sort})`);\n\n const optsStr = findOptions.length > 0 ? `,\\n${indent(1)}${findOptions.join(`,\\n${indent(1)}`)}` : ''\n\n return []\n .concat(comment)\n .concat(connect)\n .concat('')\n .concat(`${coll}`)\n .concat(`_, err = coll.${driverMethod}(ctx, ${filter}${optsStr})`)\n .concat('if err != nil {')\n .concat(' log.Fatal(err)')\n .concat('}')\n .join('\\n');\n }\n EqualitySyntaxTemplate: !!js/function &EqualitySyntaxTemplate >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n }\n else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: !!js/function &InSyntaxTemplate >\n (lhs, op, rhs) => {\n this.declarations.addFunc([]\n .concat(`var contains = func(elems bson.A, v interface{}) bool {`)\n .concat(' for _, s := range elems {')\n .concat(' if v == s {')\n .concat(' return true')\n .concat(' }')\n .concat(' }')\n .concat(' return false')\n .concat('}')\n .join('\\n'));\n let prefix = '';\n if (op.includes('!') || op.includes('not'))\n prefix = '!';\n return `${prefix}contains(${rhs}, ${lhs})`;\n }\n AndSyntaxTemplate: !!js/function &AndSyntaxTemplate >\n (args) => args.join(' && ')\n OrSyntaxTemplate: !!js/function &OrSyntaxTemplate >\n (args) => args.join(' || ')\n NotSyntaxTemplate: !!js/function &NotSyntaxTemplate >\n (arg) => `!${arg}`\n UnarySyntaxTemplate: !!js/function &UnarySyntaxTemplate >\n (op, val) => {\n switch(op) {\n case '+':\n return val;\n case '~':\n return `!${val}`;\n default:\n return `${op}${val}`;\n }\n return `${op}${val}`;\n }\n BinarySyntaxTemplate: !!js/function &BinarySyntaxTemplate >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `${s} / ${rhs}`\n case '**':\n return `math.Pow(${s}, ${rhs})`\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosTemplate: &EosSyntaxTemplate null # No args. End-of-line\n EofTemplate: &EofSyntaxTemplate null # No args. End-of-file\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: !!js/function &StringTypeTemplate >\n (str) => {\n // Double quote stringify\n const singleQuoted = str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'';\n const doubleQuoted = str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n str = str.substr(1, str.length - 2);\n return `\"${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n RegexTypeTemplate: !!js/function &RegexTypeTemplate >\n (pattern, flags) => {\n // Wrap string in double quotes\n const doubleStringify = (str) => {\n const singleQuoted = str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'';\n const doubleQuoted = str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n str = str.substr(1, str.length - 2);\n return `\"${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n\n const structParts = [];\n structParts.push(`Pattern: ${doubleStringify(pattern)}`);\n if (flags)\n structParts.push(`Options: ${doubleStringify(flags)}`);\n return `primitive.Regex{${structParts.join(\", \")}}`;\n }\n BoolTypeTemplate: !!js/function &BoolTypeTemplate >\n (literal) => literal.toLowerCase()\n IntegerTypeTemplate: &IntegerTypeTemplate null # args: literal, argType (i.e. '_string', '_decimal' etc)\n DecimalTypeTemplate: &DecimalTypeTemplate null # args: literal, argType\n LongBasicTypeTemplate: &LongBasicTypeTemplate null # args: literal, argType\n HexTypeTemplate: &HexTypeTemplate null # args: literal, argType\n OctalTypeTemplate: &OctalTypeTemplate null # args: literal, argType\n NumericTypeTemplate: &NumericTypeTemplate null # args: literal, argType\n ArrayTypeTemplate: !!js/function &ArrayTypeTemplate >\n (literal, depth) => {\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n if (literal === '')\n return 'bson.A{}';\n return `bson.A{${literal}${closingIndent}}`;\n }\n ArrayTypeArgsTemplate: !!js/function &ArrayTypeArgsTemplate >\n (arg, depth, last) => {\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n return `${indent}${arg},`;\n }\n NullTypeTemplate: !!js/function &NullTypeTemplate >\n () => 'primitive.Null{}'\n UndefinedTypeTemplate: !!js/function &UndefinedTypeTemplate >\n () => 'primitive.Undefined{}'\n ObjectTypeTemplate: !!js/function &ObjectTypeTemplate >\n (literal) => `bson.D{${literal}}`\n ObjectTypeArgsTemplate: !!js/function &ObjectTypeArgsTemplate >\n (args, depth) => {\n // If there are no args, then there is nothing for us to format\n if (args.length === 0)\n return '';\n\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n\n // Indent every line of a string\n const indentBlock = (string, count = 1, options = {}) => {\n const {\n indent = ' ',\n includeEmptyLines = false\n } = options;\n\n const regex = includeEmptyLines ? /^/gm : /^(?!\\s*$)/gm;\n return string.replace(regex, indent.repeat(count));\n }\n\n // Wrap string in double quotes\n const doubleStringify = (str) => {\n const singleQuoted = str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'';\n const doubleQuoted = str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n str = str.substr(1, str.length - 2);\n return `\"${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n\n // Check if a string is multiple lines i.e. has a break point\n const isMultiline = (element) => /\\r|\\n/.exec(element)\n\n // Format element by go type\n const fmt = (element) => {\n const hash = { multiline: isMultiline(element) };\n const typeFormatters = {\n 'bson.A': (el, hash) => isMultiline(el) ? indentBlock(`${indent}${el},${indent}`) : ` ${el}`,\n 'bson.D': (el, hash) => isMultiline(el) ? indentBlock(`${indent}${el},${indent}`) : ` ${el}`,\n default: (el, hash) => isMultiline(el) ? el : ` ${el}`\n };\n hash.el = typeFormatters.default(element);\n for (const type in typeFormatters)\n if (element.startsWith(type)) {\n hash.el = typeFormatters[type](element);\n break;\n }\n return hash;\n }\n\n // Get the {key, value} pair for the bson.D object\n const getPairs = (args, sep = `,${indent}`) => {\n const hash = { multiline: false }\n hash.el = args.map((pair) => {\n const fmtPair = fmt(pair[1])\n if (!hash.multiline && fmtPair.multiline)\n hash.multiline = true\n return `{${doubleStringify(pair[0])},${fmtPair.el}}`\n }).join(sep)\n return hash\n }\n\n const pairs = getPairs(args);\n const singleLine = args.length <= 1 && !pairs.multiline;\n const prefix = singleLine ? '' : indent;\n const suffix = singleLine ? '' : ',' + closingIndent;\n return `${prefix}${pairs.el}${suffix}`;\n }\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don't take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: !!js/function &CodeSymbolTemplate >\n () => 'primitive.CodeWithScope'\n CodeSymbolArgsTemplate: !!js/function &CodeSymbolArgsTemplate >\n (_, code, scope) => {\n if (code === undefined)\n return `{}`;\n\n if (scope !== undefined)\n scope = `Scope: ${scope}`;\n\n const singleQuoted = code.charAt(0) === '\\'' && code.charAt(code.length - 1) === '\\'';\n const doubleQuoted = code.charAt(0) === '\"' && code.charAt(code.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n code = code.substr(1, code.length - 2);\n\n code = `Code: primitive.JavaScript(\"${code.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n return (scope === undefined) ? `{${code}}` : `{${code}, ${scope}}`;\n }\n ObjectIdSymbolTemplate: !!js/function &ObjectIdSymbolTemplate >\n () => ''\n ObjectIdSymbolArgsTemplate: !!js/function &ObjectIdSymbolArgsTemplate >\n (_, arg) => {\n if (arg === undefined || arg === '')\n return 'primitive.NewObjectID()';\n\n // Double quote stringify\n const singleQuoted = arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'';\n const doubleQuoted = arg.charAt(0) === '\"' && arg.charAt(arg.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n arg = arg.substr(1, arg.length - 2);\n arg = `\"${arg.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n this.declarations.addFunc([]\n .concat('var objectIDFromHex = func(hex string) primitive.ObjectID {')\n .concat(` objectID, err := primitive.ObjectIDFromHex(hex)`)\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return objectID')\n .concat('}')\n .join('\\n'));\n return `objectIDFromHex(${arg})`\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate null\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate null\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate null\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate null\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate null\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate null\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template null\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate null\n DBRefSymbolTemplate: &DBRefSymbolTemplate null # No args\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null\n DoubleSymbolTemplate: !!js/function &DoubleSymbolTemplate >\n () => ''\n DoubleSymbolArgsTemplate: !!js/function &DoubleSymbolArgsTemplate >\n (lhs, arg, type) => {\n if (!arg)\n arg = 0;\n switch(type) {\n case '_string':\n this.declarations.addFunc([]\n .concat('var parseFloat64 = func(str string) float64 {')\n .concat(' f64, err := strconv.ParseFloat(str, 64)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return f64')\n .concat('}')\n .join('\\n'));\n return `parseFloat64(${arg})`\n default:\n return `float64(${arg})`;\n }\n }\n Int32SymbolTemplate: !!js/function &Int32SymbolTemplate >\n () => ''\n Int32SymbolArgsTemplate: !!js/function &Int32SymbolArgsTemplate >\n (lhs, arg, type) => {\n if (!arg)\n arg = 0\n switch(type) {\n case '_string':\n this.declarations.addFunc([]\n .concat('var parseInt32 = func(str string) int32 {')\n .concat('i64, err := strconv.ParseInt(str, 10, 32)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return int32(i64)')\n .concat('}')\n .join('\\n'));\n return `parseInt32(${arg})`;\n default:\n return `int32(${arg})`;\n }\n }\n LongSymbolTemplate: !!js/function &LongSymbolTemplate >\n () => ''\n LongSymbolArgsTemplate: !!js/function &LongSymbolArgsTemplate >\n (lhs, arg, type) => {\n if (!arg)\n arg = 0\n switch(type) {\n case '_string':\n this.declarations.addFunc([]\n .concat('var parseInt = func(str string) int64 {')\n .concat(' i64, err := strconv.ParseInt(str, 10, 64)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return i64')\n .concat('}')\n .join('\\n'));\n return `parseInt64(${arg})`;\n default:\n return `int64(${arg})`;\n }\n }\n RegExpSymbolTemplate: !!js/function &RegExpSymbolTemplate >\n () => 'regex'\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: !!js/function &SymbolSymbolTemplate >\n () => 'primitive.Symbol'\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate null\n BSONRegExpSymbolTemplate: !!js/function &BSONRegExpSymbolTemplate >\n () => 'primitive.Regex'\n BSONRegExpSymbolArgsTemplate: !!js/function &BSONRegExpSymbolArgsTemplate >\n (_, pattern, flags) => {\n // Wrap string in double quotes\n const doubleStringify = (str) => {\n const singleQuoted = str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'';\n const doubleQuoted = str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n str = str.substr(1, str.length - 2);\n return `\"${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n\n const structParts = [];\n structParts.push(`Pattern: ${doubleStringify(pattern)}`);\n if (flags)\n structParts.push(`Options: ${doubleStringify(flags)}`);\n return `(${structParts.join(\", \")})`;\n }\n Decimal128SymbolTemplate: !!js/function &Decimal128SymbolTemplate >\n () => ''\n Decimal128SymbolArgsTemplate: !!js/function &Decimal128SymbolArgsTemplate >\n (_, arg) => {\n if (!arg)\n arg = '\"0\"';\n\n // Double quote stringify\n const singleQuoted = arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'';\n const doubleQuoted = arg.charAt(0) === '\"' && arg.charAt(arg.length - 1) === '\"';\n if (singleQuoted || doubleQuoted)\n arg = arg.substr(1, arg.length - 2);\n arg = `\"${arg.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n\n this.declarations.addFunc([]\n .concat('var parseDecimal128 = func(str string) primitive.Decimal128 {')\n .concat(' d128, err := primitive.ParseDecimal128(str)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return d128')\n .concat('}')\n .join('\\n'));\n return `parseDecimal128(${arg})`;\n }\n MinKeySymbolTemplate: !!js/function &MinKeySymbolTemplate >\n () => 'primitive.MinKey'\n MinKeySymbolArgsTemplate: !!js/function &MinKeySymbolArgsTemplate >\n () => '{}'\n MaxKeySymbolTemplate: !!js/function &MaxKeySymbolTemplate >\n () => 'primitive.MaxKey'\n MaxKeySymbolArgsTemplate: !!js/function &MaxKeySymbolArgsTemplate >\n () => '{}'\n TimestampSymbolTemplate: !!js/function &TimestampSymbolTemplate >\n () => 'primitive.Timestamp'\n TimestampSymbolArgsTemplate: !!js/function &TimestampSymbolArgsTemplate >\n (lhs, low, high) => {\n if (low === undefined) {\n low = 0;\n high = 0;\n }\n return `{T: ${low}, I: ${high}}`\n }\n # non bson-specific\n NumberSymbolTemplate: !!js/function &NumberSymbolTemplate >\n () => ''\n NumberSymbolArgsTemplate: !!js/function &NumberSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n switch(type) {\n case '_string':\n if (arg.indexOf('.') !== -1) {\n this.declarations.addFunc([]\n .concat('var parseFloat64 = func(str string) float64 {')\n .concat(' f64, err := strconv.ParseFloat(str, 64)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return f64')\n .concat('}')\n .join('\\n'));\n return `parseFloat64(${arg})`\n }\n this.declarations.addFunc([]\n .concat('var parseInt = func(str string) int64 {')\n .concat(' i64, err := strconv.ParseInt(str, 10, 64)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return i64')\n .concat('}')\n .join('\\n'));\n return `parseInt64(${arg})`;\n default:\n return `${arg}`\n }\n }\n DateSymbolTemplate: !!js/function &DateSymbolTemplate >\n () => 'time.Date'\n DateSymbolArgsTemplate: !!js/function &DateSymbolArgsTemplate >\n (lhs, date, isString) => {\n if (date === null)\n return `time.Now()`;\n\n const dateStr = [\n date.getUTCFullYear(),\n date.getUTCMonth() + 1,\n date.getUTCDate(),\n date.getUTCHours(),\n date.getUTCMinutes(),\n date.getUTCSeconds(),\n '0',\n 'time.UTC'\n ].join(', ');\n\n return `${lhs}(${dateStr})`\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These're variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: !!js/function &CodeCodeTemplate >\n (lhs) => `${lhs}.Code`\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: !!js/function &CodeScopeTemplate >\n (lhs) => lhs\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: !!js/function &ObjectIdToStringTemplate >\n (lhs) => `${lhs}.String()`\n ObjectIdToStringArgsTemplate: !!js/function &ObjectIdToStringArgsTemplate >\n () => ''\n ObjectIdEqualsTemplate: !!js/function &ObjectIdEqualsTemplate >\n () => ''\n ObjectIdEqualsArgsTemplate: !!js/function &ObjectIdEqualsArgsTemplate >\n (arg1, arg2) => `${arg1} == ${arg2}`\n ObjectIdGetTimestampTemplate: !!js/function &ObjectIdGetTimestampTemplate >\n (lhs) => `${lhs}.Timestamp()`\n ObjectIdGetTimestampArgsTemplate:\n !!js/function &ObjectIdGetTimestampArgsTemplate >\n () => ''\n ObjectIdIsValidTemplate: !!js/function &ObjectIdIsValidTemplate >\n () => `primitive.IsValidObjectID`\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate null\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: &BinarySubtypeTemplate null\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate null\n DBRefGetDBTemplate: &DBRefGetDBTemplate null\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate null\n DBRefGetIdTemplate: &DBRefGetIdTemplate null\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate null\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate null\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate null\n DBRefToStringTemplate: &DBRefToStringTemplate null\n DBRefToStringArgsTemplate: &DBRefToStringArgsTemplate null\n DoubleValueOfTemplate: &DoubleValueOfTemplate null\n DoubleValueOfArgsTemplate: &DoubleValueOfArgsTemplate null\n Int32ValueOfTemplate: &Int32ValueOfTemplate null\n Int32ValueOfArgsTemplate: &Int32ValueOfArgsTemplate null\n Int32ToStringTemplate: &Int32ToStringTemplate null\n Int32ToStringArgsTemplate: &Int32ToStringArgsTemplate null\n LongEqualsTemplate: !!js/function &LongEqualsTemplate >\n (lhs) => `${lhs} == `\n LongEqualsArgsTemplate: !!js/function &LongEqualsArgsTemplate >\n (_, arg) => arg\n LongToStringTemplate: !!js/function &LongToStringTemplate >\n (lhs) => `strconv.Itoa(${lhs})`\n LongToStringArgsTemplate: !!js/function &LongToStringArgsTemplate >\n () => ''\n LongToIntTemplate: !!js/function &LongToIntTemplate >\n (lhs) => `int(${lhs})`\n LongToIntArgsTemplate: !!js/function &LongToIntArgsTemplate >\n () => ''\n LongValueOfTemplate: &LongValueOfTemplate null\n LongValueOfArgsTemplate: &LongValueOfArgsTemplate null\n LongToNumberTemplate: !!js/function &LongToNumberTemplate >\n (lhs) => `float64(${lhs})`\n LongToNumberArgsTemplate: !!js/function &LongToNumberArgsTemplate >\n (arg) => ''\n LongAddTemplate: !!js/function &LongAddTemplate >\n (lhs) => `${lhs} + `\n LongAddArgsTemplate: !!js/function &LongAddArgsTemplate >\n (_, args) => args\n LongSubtractTemplate: !!js/function &LongSubtractTemplate >\n (lhs) => `${lhs} - `\n LongSubtractArgsTemplate: !!js/function &LongSubtractArgsTemplate >\n (_, arg) => arg\n LongMultiplyTemplate: !!js/function &LongMultiplyTemplate >\n (lhs) => `${lhs} * `\n LongMultiplyArgsTemplate: !!js/function &LongMultiplyArgsTemplate >\n (_, arg) => arg\n LongDivTemplate: !!js/function &LongDivTemplate >\n (lhs) => `${lhs} / `\n LongDivArgsTemplate: !!js/function &LongDivArgsTemplate >\n (_, arg) => arg\n LongModuloTemplate: !!js/function &LongModuloTemplate >\n (lhs) => `${lhs} % `\n LongModuloArgsTemplate: !!js/function &LongModuloArgsTemplate >\n (_, arg) => arg\n LongAndTemplate: !!js/function &LongAndTemplate >\n (lhs) => `${lhs} & `\n LongAndArgsTemplate: !!js/function &LongAndArgsTemplate >\n (_, arg) => arg\n LongOrTemplate: !!js/function &LongOrTemplate >\n (lhs) => `${lhs} | `\n LongOrArgsTemplate: !!js/function &LongOrArgsTemplate >\n (_, arg) => arg\n LongXorTemplate: !!js/function &LongXorTemplate >\n (lhs) => `${lhs} ^ `\n LongXorArgsTemplate: !!js/function &LongXorArgsTemplate >\n (_, arg) => arg\n LongShiftLeftTemplate: !!js/function &LongShiftLeftTemplate >\n (lhs) => `${lhs} << `\n LongShiftLeftArgsTemplate: !!js/function &LongShiftLeftArgsTemplate >\n (_, rhs) => rhs\n LongShiftRightTemplate: !!js/function &LongShiftRightTemplate >\n (lhs) => `${lhs} >> `\n LongShiftRightArgsTemplate: !!js/function &LongShiftRightArgsTemplate >\n (_, rhs) => rhs\n LongCompareTemplate: !!js/function &LongCompareTemplate >\n (lhs) => `${lhs} - `\n LongCompareArgsTemplate: !!js/function &LongCompareArgsTemplate >\n (_, rhs) => rhs\n LongIsOddTemplate: !!js/function &LongIsOddTemplate >\n (arg) => `${arg} % 2 == 1`\n LongIsOddArgsTemplate: !!js/function &LongIsOddArgsTemplate >\n () => ''\n LongIsZeroTemplate: !!js/function &LongIsZeroTemplate >\n (arg) => `${arg} == int64(0)`\n LongIsZeroArgsTemplate: !!js/function &LongIsZeroArgsTemplate >\n () => ''\n LongIsNegativeTemplate: !!js/function &LongIsNegativeTemplate >\n (arg) => `${arg} < int64(0)`\n LongIsNegativeArgsTemplate: !!js/function &LongIsNegativeArgsTemplate >\n () => ''\n LongNegateTemplate: !!js/function &LongNegateTemplate >\n () => '-'\n LongNegateArgsTemplate: !!js/function &LongNegateArgsTemplate >\n (lhs) => lhs\n LongNotTemplate: !!js/function &LongNotTemplate >\n () => '^'\n LongNotArgsTemplate: !!js/function &LongNotArgsTemplate >\n (lhs) => lhs\n LongNotEqualsTemplate: !!js/function &LongNotEqualsTemplate >\n (lhs) => `${lhs} != `\n LongNotEqualsArgsTemplate: !!js/function &LongNotEqualsArgsTemplate >\n (_, rhs) => rhs\n LongGreaterThanTemplate: !!js/function &LongGreaterThanTemplate >\n (lhs) => `${lhs} > `\n LongGreaterThanArgsTemplate: !!js/function &LongGreaterThanArgsTemplate >\n (_, rhs) => rhs\n LongGreaterThanOrEqualTemplate:\n !!js/function &LongGreaterThanOrEqualTemplate >\n (lhs) => `${lhs} >= `\n LongGreaterThanOrEqualArgsTemplate:\n !!js/function &LongGreaterThanOrEqualArgsTemplate >\n (_, rhs) => rhs\n LongLessThanTemplate: !!js/function &LongLessThanTemplate >\n (lhs) => `${lhs} < `\n LongLessThanArgsTemplate: !!js/function &LongLessThanArgsTemplate >\n (_, rhs) => rhs\n LongLessThanOrEqualTemplate: !!js/function &LongLessThanOrEqualTemplate >\n (lhs) => `${lhs} <= `\n LongLessThanOrEqualArgsTemplate:\n !!js/function &LongLessThanOrEqualArgsTemplate >\n (_, rhs) => rhs\n LongFloatApproxTemplate: !!js/function &LongFloatApproxTemplate >\n (arg) => `float64(${arg})`\n LongTopTemplate: !!js/function &LongTopTemplate >\n (arg) => `${arg} >> 32`\n LongBottomTemplate: !!js/function &LongBottomTemplate >\n (arg) => `${arg} & 0x0000ffff`\n TimestampToStringTemplate: !!js/function &TimestampToStringTemplate >\n (lhs) => `time.Unix(${lhs}.T, 0).String`\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n () => '()'\n TimestampEqualsTemplate: !!js/function &TimestampEqualsTemplate >\n (lhs) => `${lhs}.Equal`\n TimestampEqualsArgsTemplate: !!js/function &TimestampEqualsArgsTemplate >\n (_, rhs) => `(${rhs})`\n TimestampGetLowBitsTemplate: !!js/function &TimestampGetLowBitsTemplate >\n (lhs) => `${lhs}.T`\n TimestampGetLowBitsArgsTemplate:\n !!js/function &TimestampGetLowBitsArgsTemplate >\n () => ''\n TimestampGetHighBitsTemplate: !!js/function &TimestampGetHighBitsTemplate >\n (lhs) => `${lhs}.I`\n TimestampGetHighBitsArgsTemplate:\n !!js/function &TimestampGetHighBitsArgsTemplate >\n () => ''\n TimestampTTemplate: !!js/function &TimestampTTemplate >\n (lhs) => `${lhs}.T`\n TimestampITemplate: !!js/function &TimestampITemplate >\n (lhs) => `${lhs}.I`\n TimestampAsDateTemplate: !!js/function &TimestampAsDateTemplate >\n (lhs) => `time.Unix(${lhs}.T, 0)`\n TimestampAsDateArgsTemplate: !!js/function &TimestampAsDateArgsTemplate >\n () => ''\n TimestampCompareTemplate: !!js/function &TimestampCompareTemplate >\n () => 'primitive.CompareTimestamp'\n TimestampCompareArgsTemplate: !!js/function &TimestampCompareArgsTemplate >\n (lhs, rhs) => `(${lhs}, ${rhs})`\n TimestampNotEqualsTemplate: !!js/function &TimestampNotEqualsTemplate >\n (lhs) => `!${lhs}.Equal`\n TimestampNotEqualsArgsTemplate:\n !!js/function &TimestampNotEqualsArgsTemplate >\n (_, rhs) => `(${rhs})`\n TimestampGreaterThanTemplate: !!js/function &TimestampGreaterThanTemplate >\n () => ''\n TimestampGreaterThanArgsTemplate:\n !!js/function &TimestampGreaterThanArgsTemplate >\n (lhs, rhs) => `primitive.CompareTimestamp(${lhs}, ${rhs}) == 1`\n TimestampGreaterThanOrEqualTemplate:\n !!js/function &TimestampGreaterThanOrEqualTemplate >\n () => ''\n TimestampGreaterThanOrEqualArgsTemplate:\n !!js/function &TimestampGreaterThanOrEqualArgsTemplate >\n (arg1, arg2) => `primitive.CompareTimestamp(${arg1}, ${arg2}) >= 0`\n TimestampLessThanTemplate: !!js/function &TimestampLessThanTemplate >\n (lhs) => ''\n TimestampLessThanArgsTemplate: !!js/function &TimestampLessThanArgsTemplate >\n (lhs, rhs) => `primitive.CompareTimestamp(${lhs}, ${rhs}) == -1`\n TimestampLessThanOrEqualTemplate:\n !!js/function &TimestampLessThanOrEqualTemplate >\n () => ''\n TimestampLessThanOrEqualArgsTemplate:\n !!js/function &TimestampLessThanOrEqualArgsTemplate >\n (arg1, arg2) => `primitive.CompareTimestamp(${arg1}, ${arg2}) <= 0`\n SymbolValueOfTemplate: !!js/function &SymbolValueOfTemplate >\n () => ''\n SymbolValueOfArgsTemplate: !!js/function &SymbolValueOfArgsTemplate >\n (arg) => arg\n SymbolInspectTemplate: !!js/function &SymbolInspectTemplate >\n () => ''\n SymbolInspectArgsTemplate: !!js/function &SymbolInspectArgsTemplate >\n (arg) => arg\n SymbolToStringTemplate: !!js/function &SymbolToStringTemplate >\n () => ''\n SymbolToStringArgsTemplate: !!js/function &SymbolToStringArgsTemplate >\n (lhs) => `string(${lhs})`\n Decimal128ToStringTemplate: !!js/function &Decimal128ToStringTemplate >\n (lhs) => `${lhs}.String()`\n Decimal128ToStringArgsTemplate:\n !!js/function &Decimal128ToStringArgsTemplate >\n () => ''\n # non bson-specific\n DateSymbolNowTemplate: !!js/function &DateSymbolNowTemplate >\n () => 'time.Now()'\n DateSymbolNowArgsTemplate: !!js/function &DateSymbolNowArgsTemplate >\n () => ''\n\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These're variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don't overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: !!js/function &LongSymbolMaxTemplate >\n () => 'int(^uint(0) >> 1)'\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: !!js/function &LongSymbolMinTemplate >\n () => '-(1+int(^uint(0) >> 1))'\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: !!js/function &LongSymbolZeroTemplate >\n () => 'int64(0)'\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: !!js/function &LongSymbolOneTemplate >\n () => 'int64(1)'\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: !!js/function &LongSymbolNegOneTemplate >\n () => 'int64(-1)'\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: !!js/function &LongSymbolFromBitsTemplate >\n () => 'int64'\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: !!js/function &LongSymbolFromIntTemplate >\n () => 'int64'\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate null\n LongSymbolFromNumberTemplate: !!js/function &LongSymbolFromNumberTemplate >\n () => 'int64'\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: !!js/function &LongSymbolFromStringTemplate >\n () => ''\n LongSymbolFromStringArgsTemplate:\n !!js/function &LongSymbolFromStringArgsTemplate >\n (_, arg) => {\n this.declarations.addFunc([]\n .concat('var int64FromString = func(str string) int64 {')\n .concat(' f64, err := strconv.Atoi(str)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return f64')\n .concat('}')\n .join('\\n'));\n return `int64FromString(${arg})`;\n }\n Decimal128SymbolFromStringTemplate:\n !!js/function &Decimal128SymbolFromStringTemplate >\n () => ''\n Decimal128SymbolFromStringArgsTemplate:\n !!js/function &Decimal128SymbolFromStringArgsTemplate >\n (_, arg) => {\n this.declarations.addFunc([]\n .concat('var parseDecimal128 = func(str string) primitive.Decimal128 {')\n .concat(' d128, err := primitive.ParseDecimal128(str)')\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return d128')\n .concat('}')\n .join('\\n'));\n return `parseDecimal128(${arg})`;\n }\n ObjectIdCreateFromHexStringTemplate:\n !!js/function &ObjectIdCreateFromHexStringTemplate >\n () => ''\n ObjectIdCreateFromHexStringArgsTemplate:\n !!js/function &ObjectIdCreateFromHexStringArgsTemplate >\n (_, arg) => {\n this.declarations.addFunc([]\n .concat('var objectIDFromHex = func(hex string) primitive.ObjectID {')\n .concat(` objectID, err := primitive.ObjectIDFromHex(hex)`)\n .concat(' if err != nil {')\n .concat(' log.Fatal(err)')\n .concat(' }')\n .concat(' return objectID')\n .concat('}')\n .join('\\n'));\n return `objectIDFromHex(${arg})`\n }\n ObjectIdCreateFromTimeTemplate:\n !!js/function &ObjectIdCreateFromTimeTemplate >\n () => 'primitive.NewObjectIDFromTimestamp'\n ObjectIdCreateFromTimeArgsTemplate:\n !!js/function &ObjectIdCreateFromTimeArgsTemplate >\n (_, arg, isNumber) => isNumber ? `(time.Unix(${arg}, int64(0)))` : `(${arg})`\n # non bson-specific would go here, but there aren't any atm.\n #############################################\n # Imports #\n # #\n # Each type has a 'code' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: !!js/function &ImportTemplate >\n (args) => {\n const imports = Object.values(args).flat()\n const driverImports = args.driver || [];\n delete args['driver'];\n\n const flattenedArgs = Array.from(new Set([...driverImports, ...imports])).sort();\n const universal = [];\n const all = universal\n .concat(flattenedArgs)\n .map((i) => ` \"${i}\"`);\n return []\n .concat('import (')\n .concat(all.join('\\n'))\n .concat(')')\n .join('\\n');\n }\n DriverImportTemplate: !!js/function &DriverImportTemplate >\n () => {\n return [\n \"go.mongodb.org/mongo-driver/mongo\",\n \"go.mongodb.org/mongo-driver/mongo/options\",\n \"context\",\n \"log\"\n ]\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: !!js/function &8ImportTemplate >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: !!js/function &10ImportTemplate >\n () => ['go.mongodb.org/mongo-driver/bson']\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: !!js/function &100ImportTemplate >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 101ImportTemplate: !!js/function &101ImportTemplate >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive', 'log']\n 102ImportTemplate: &102ImportTemplate null\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: !!js/function &104ImportTemplate >\n (args) => ['log', 'strconv']\n 105ImportTemplate: !!js/function &105ImportTemplate >\n (args) => ['log', 'strconv']\n 106ImportTemplate: !!js/function &106ImportTemplate >\n (args) => ['log', 'strconv']\n 107ImportTemplate: !!js/function &107ImportTemplate >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 108ImportTemplate: !!js/function &108ImportTemplate >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 109ImportTemplate: !!js/function &109ImportTemplate >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 110ImportTemplate: !!js/function &110ImportTemplate >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 111ImportTemplate: !!js/function &111ImportTemplate >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive']\n 112ImportTemplate: !!js/function &112ImportTemplate >\n (args) => ['go.mongodb.org/mongo-driver/bson/primitive', 'log']\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: !!js/function &200ImportTemplate >\n (args) => ['time.Time']\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; diff --git a/packages/bson-transpilers/lib/symbol-table/shelltojava.js b/packages/bson-transpilers/lib/symbol-table/shelltojava.js index 5b62e7ce5a0..a4575be2085 100644 --- a/packages/bson-transpilers/lib/symbol-table/shelltojava.js +++ b/packages/bson-transpilers/lib/symbol-table/shelltojava.js @@ -1 +1,2 @@ -module.exports="SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n\n# Java Templates\nTemplates:\n # Misc\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'u'\n y: ''\n g: ''\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n # Syntax\n DriverTemplate: &DriverTemplate !!js/function >\n (spec) => {\n const comment = `/*\n * Requires the MongoDB Java Driver.\n * https://mongodb.github.io/mongo-java-driver`;\n\n const str = spec.options.uri;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n const uri = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n const exportMode = spec.exportMode;\n delete spec.exportMode;\n\n const connection = `MongoClient mongoClient = new MongoClient(\n new MongoClientURI(\n ${uri}\n )\n );\n\n MongoDatabase database = mongoClient.getDatabase(\"${spec.options.database}\");\n\n MongoCollection collection = database.getCollection(\"${spec.options.collection}\");`;\n\n let driverMethod;\n let driverResult;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'deleteMany';\n driverResult = 'DeleteResult';\n break;\n case 'Update Query':\n driverMethod = 'updateMany';\n driverResult = 'UpdateResult';\n break;\n default:\n driverMethod = 'find';\n driverResult = 'FindIterable';\n }\n if ('aggregation' in spec) {\n return `${comment}\\n */\\n\\n${connection}\n\n AggregateIterable result = collection.aggregate(${spec.aggregation});`;\n }\n\n let warning = '';\n const defs = Object.keys(spec).reduce((s, k) => {\n if (!spec[k]) return s;\n if (k === 'options' || k === 'maxTimeMS' || k === 'skip' || k === 'limit' || k === 'collation') return s;\n if (s === '') return `Bson ${k} = ${spec[k]};`;\n return `${s}\n Bson ${k} = ${spec[k]};`;\n }, '');\n\n const result = Object.keys(spec).reduce((s, k) => {\n switch (k) {\n case 'options':\n case 'filter':\n return s;\n case 'maxTimeMS':\n return `${s}\n .maxTime(${spec[k]}, TimeUnit.MICROSECONDS)`;\n case 'skip':\n case 'limit':\n return `${s}\n .${k}((int)${spec[k]})`;\n case 'project':\n return `${s}\n .projection(project)`;\n case 'collation':\n warning = '\\n *\\n * Warning: translating collation to Java not yet supported, so will be ignored';\n return s;\n case 'exportMode':\n return s;\n default:\n if (!spec[k]) return s;\n return `${s}\n .${k}(${k})`;\n }\n }, `${driverResult} result = collection.${driverMethod}(filter)`);\n\n return `${comment}${warning}\\n */\\n\\n${defs}\n\n ${connection}\n\n ${result};`;\n }\n EqualitySyntaxTemplate: &EqualitySyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n } else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: &InSyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n let str = '';\n if (op.includes('!') || op.includes('not')) {\n str = '!';\n }\n return `${str}${rhs}.contains(${lhs})`\n }\n AndSyntaxTemplate: &AndSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: &OrSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: &NotSyntaxTemplate !!js/function >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: &BinarySyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `floor(${s})`;\n case '**':\n return `pow(${s}, ${rhs})`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosSyntaxTemplate: &EosSyntaxTemplate null\n EofSyntaxTemplate: &EofSyntaxTemplate null\n NewTemplate: &NewSyntaxTemplate !!js/function >\n (expr, skip, code) => {\n // Add codes of classes that don't need new.\n // Currently: Decimal128/NumberDecimal, Long/NumberLong, Double, Int32, Number, regex, Date\n noNew = [112, 106, 104, 105, 2, 8, 200];\n if (skip || (code && noNew.indexOf(code) !== -1)) {\n return expr;\n }\n return `new ${expr}`;\n }\n # BSON Object Type templates\n CodeTypeTemplate: &CodeTypeTemplate null\n StringTypeTemplate: &StringTypeTemplate !!js/function >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n RegexTypeTemplate: &RegexTypeTemplate !!js/function >\n (pattern, flags) => {\n flags = flags === '' ? '' : `(?${flags})`;\n // Double escape characters except for slashes\n const escaped = pattern.replace(/\\\\/, '\\\\\\\\');\n\n // Double-quote stringify\n const str = escaped + flags;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `Pattern.compile(\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n BoolTypeTemplate: &BoolTypeTemplate !!js/function >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null\n DecimalTypeTemplate: &DecimalTypeTemplate !!js/function >\n (literal, type) => {\n if (type === '_integer' || type === '_long' || type === '_decimal') {\n return `${literal}d`;\n }\n return `(double) ${literal}`;\n }\n LongBasicTypeTemplate: &LongBasicTypeTemplate !!js/function >\n (literal, type) => {\n if (type === '_integer' || type === '_long') {\n return `${literal}L`;\n }\n return `new Long(${literal})`;\n }\n HexTypeTemplate: &HexTypeTemplate null # TODO\n OctalTypeTemplate: &OctalTypeTemplate !!js/function >\n (literal, type) => {\n if ((literal.charAt(0) === '0' && literal.charAt(1) === '0') ||\n (literal.charAt(0) === '0' && (literal.charAt(1) === 'o' || literal.charAt(1) === 'O'))) {\n return `0${literal.substr(2, literal.length - 1)}`;\n }\n return literal;\n }\n NumericTypeTemplate: &NumericTypeTemplate null\n ArrayTypeTemplate: &ArrayTypeTemplate !!js/function >\n (literal, depth) => {\n depth++;\n // TODO: figure out how to best do depth in an array and where to\n // insert and indent\n const indent = '\\n' + ' '.repeat(depth);\n // have an indent on every ', new Document' in an array not\n // entirely perfect, but at least makes this more readable/also\n // compiles\n const arr = literal.split(', new').join(`, ${indent}new`)\n\n return `Arrays.asList(${arr})`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null\n NullTypeTemplate: &NullTypeTemplate !!js/function >\n () => {\n return 'new BsonNull()';\n }\n UndefinedTypeTemplate: &UndefinedTypeTemplate !!js/function >\n () => {\n return 'new BsonUndefined()';\n }\n ObjectTypeTemplate: &ObjectTypeTemplate !!js/function >\n (literal, depth) => {\n\n if (literal === '') {\n return `new Document()`;\n }\n return literal;\n }\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate !!js/function >\n (args, depth) => {\n if (args.length === 0) {\n return 'new Document()';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n const start = `new Document(${doubleStringify(args[0][0])}, ${args[0][1]})`;\n\n args = args.slice(1);\n const result = args.reduce((str, pair) => {\n return `${str}${indent}.append(${doubleStringify(pair[0])}, ${pair[1]})`;\n }, start);\n\n return `${result}`;\n }\n DoubleTypeTemplate: &DoubleTypeTemplate !!js/function >\n (literal, type) => {\n if (type === '_integer' || type === '_long' || type === '_decimal') {\n return `${literal}d`;\n }\n return `(double) ${literal}`;\n }\n DoubleTypeArgsTemplate: &DoubleTypeArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongTypeTemplate: &LongTemplate !!js/function >\n () => {\n return '';\n }\n LongTypeArgsTemplate: &LongSymbolArgsTemplate null\n # BSON Object Method templates\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.toHexString()`;\n }\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate null\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate null\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getTimestamp()`;\n }\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate !!js/function >\n () => {\n return '';\n }\n CodeCodeTemplate: &CodeCodeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getCode()`;\n }\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getScope()`;\n }\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getData`;\n }\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: &BinarySubtypeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getType()`;\n }\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetDBTemplate: &DBRefGetDBTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getDatabaseName()`;\n }\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getCollectionName()`;\n }\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetIdTemplate: &DBRefGetIdTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getId()`;\n }\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongEqualsTemplate: &LongEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} ==`;\n }\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongToStringTemplate: &LongToStringTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToIntTemplate: &LongToIntTemplate !!js/function >\n (lhs) => {\n return `(int) ${lhs}`;\n }\n LongToIntArgsTemplate: &LongToIntArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongToNumberTemplate: &LongToNumberTemplate !!js/function >\n (lhs) => {\n return `(double) ${lhs}`;\n }\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongAddTemplate: &LongAddTemplate !!js/function >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: &LongAddArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: &LongSubtractTemplate !!js/function >\n (arg) => {\n return `${arg} -`;\n }\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: &LongMultiplyTemplate !!js/function >\n (arg) => {\n return `${arg} *`;\n }\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: &LongDivTemplate !!js/function >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: &LongDivArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: &LongModuloTemplate !!js/function >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: &LongModuloArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: &LongAndTemplate !!js/function >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: &LongAndArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: &LongOrTemplate !!js/function >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: &LongOrArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: &LongXorTemplate !!js/function >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: &LongXorArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: &LongShiftLeftTemplate !!js/function >\n () => {\n return 'Long.rotateLeft';\n }\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${lhs}, ${arg})`;\n }\n LongShiftRightTemplate: &LongShiftRightTemplate !!js/function >\n () => {\n return 'Long.rotateRight';\n }\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${lhs}, ${arg})`;\n }\n LongCompareTemplate: &LongCompareTemplate !!js/function >\n (lhs) => {\n return `${lhs} -`;\n }\n LongCompareArgsTemplate: &LongCompareArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongIsOddTemplate: &LongIsOddTemplate !!js/function >\n (lhs) => {\n return `(${lhs} % 2) == 1`;\n }\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongIsZeroTemplate: &LongIsZeroTemplate !!js/function >\n (lhs) => {\n return `${lhs} == 0`;\n }\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongIsNegativeTemplate: &LongIsNegativeTemplate !!js/function >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongNegateTemplate: &LongNegateTemplate !!js/function >\n () => {\n return '-';\n }\n LongNegateArgsTemplate: &LongNegateArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongNotTemplate: &LongNotTemplate !!js/function >\n () => {\n return '~';\n }\n LongNotArgsTemplate: &LongNotArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongNotEqualsTemplate: &LongNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: &LongGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: &LongLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: &LongFloatApproxTemplate !!js/function >\n (lhs) => {\n return `(float) ${lhs}`;\n }\n LongTopTemplate: &LongTopTemplate !!js/function >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: &LongBottomTemplate !!js/function >\n (lhs) => {\n return `${lhs} & 0x0000ffff`;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate null\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n TimestampEqualsTemplate: &TimestampEqualsTemplate null\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate null\n TimestampGetLowBitsTemplate: &TimestampGetLowBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getTime`;\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate null\n TimestampGetHighBitsTemplate: &TimestampGetHighBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getInc`;\n }\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate null\n TimestampTTemplate: &TimestampTTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getTime()`;\n }\n TimestampITemplate: &TimestampITemplate !!js/function >\n (lhs) => {\n return `${lhs}.getInc()`;\n }\n TimestampAsDateTemplate: &TimestampAsDateTemplate !!js/function >\n (lhs) => {\n return `new java.util.Date(${lhs}.getTime())`;\n }\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate !!js/function >\n () => {\n return '';\n }\n TimestampCompareTemplate: &TimestampCompareTemplate !!js/function >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate null\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg}) != 0`;\n }\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg}) > 0`;\n }\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg}) >= 0`;\n }\n TimestampLessThanTemplate: &TimestampLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg}) < 0`;\n }\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg}) <= 0`;\n }\n SymbolValueOfTemplate: &SymbolValueOfTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getSymbol`;\n }\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate null\n SymbolInspectTemplate: &SymbolInspectTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getSymbol`;\n }\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate null\n SymbolToStringTemplate: &SymbolToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.toString`;\n }\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate null\n # Symbol Templates\n CodeSymbolTemplate: &CodeSymbolTemplate !!js/function > # Also has process method\n () => {\n return 'Code';\n }\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate !!js/function > # Also has process method\n (lhs, code, scope) => {\n // Double quote stringify\n let newStr = code === undefined ? '' : code;\n const str = newStr;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n code = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n return (scope === undefined) ? `(${code})` : `WithScope(${code}, ${scope})`;\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate null\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate !!js/function >\n (lhs, str) => {\n if (!str || str.length === 0) {\n return '()';\n }\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `(\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate !!js/function >\n (lhs, bytes, type) => {\n const str = bytes;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n bytes = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n\n if (type === null) {\n return `(${bytes}.getBytes(\"UTF-8\"))`;\n }\n return `(${type}, ${bytes}.getBytes(\"UTF-8\"))`;\n }\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.BINARY';\n }\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.FUNCTION';\n }\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.BINARY';\n }\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.UUID_LEGACY';\n }\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.UUID_STANDARD';\n }\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template !!js/function >\n () => {\n return 'BsonBinarySubType.MD5';\n }\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate !!js/function >\n () => {\n return 'BsonBinarySubType.USER_DEFINED';\n }\n DBRefSymbolTemplate: &DBRefSymbolTemplate null\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate !!js/function >\n (lhs, coll, id, db) => {\n const dbstr = db === undefined ? '' : `${db}, `;\n return `(${dbstr}${coll}, ${id})`;\n }\n DoubleSymbolTemplate: &DoubleSymbolTemplate !!js/function >\n () => {\n return '';\n }\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_string') {\n return `Double.parseDouble(${arg})`;\n }\n if (type === '_integer' || type === '_long' || type === '_double' || type === '_decimal') {\n if (arg.includes('L') || arg.includes('d')) {\n return `${arg.substr(0, arg.length - 1)}d`;\n }\n return `${arg}d`;\n }\n return `(double) ${arg}`;\n }\n Int32SymbolTemplate: &Int32SymbolTemplate !!js/function >\n () => {\n return '';\n }\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_string') {\n return `Integer.parseInt(${arg})`;\n }\n if (type === '_integer' || type === '_long') {\n if (arg.includes('L') || arg.includes('d')) {\n return arg.substr(0, arg.length - 1);\n }\n return arg;\n }\n return `(int) ${arg}`;\n }\n LongSymbolTemplate: &LongSymbolTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_string') {\n return `Long.parseLong(${arg})`;\n }\n if (type === '_integer' || type === '_long') {\n if (arg.includes('d') || arg.includes('L')) {\n return `${arg.substr(0, arg.length - 1)}L`;\n }\n return `${arg}L`;\n }\n return `new Long(${arg})`;\n }\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate !!js/function >\n () => {\n return 'Long.MAX_VALUE';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate !!js/function >\n () => {\n return 'Long.MIN_VALUE';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate !!js/function >\n () => {\n return '0L';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate !!js/function >\n () => {\n return '1L';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate !!js/function >\n () => {\n return '-1L';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate !!js/function > # Also has process method\n () => {\n return '';\n }\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}L`;\n }\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}L`;\n }\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate !!js/function >\n (lhs) => {\n return `Long.parseLong`;\n }\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate null\n MinKeySymbolTemplate: &MinKeySymbolTemplate null\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate null\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate null\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate null\n TimestampSymbolTemplate: &TimestampSymbolTemplate !!js/function >\n () => {\n return 'BSONTimestamp';\n }\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate !!js/function >\n (lhs, arg1, arg2) => {\n return `(${arg1 === undefined ? 0 : arg1}, ${arg2 === undefined ? 0 : arg2})`;\n }\n SymbolSymbolTemplate: &SymbolSymbolTemplate !!js/function >\n () => {\n return 'Symbol';\n }\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate null\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate !!js/function >\n () => {\n return 'BsonRegularExpression';\n }\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate !!js/function >\n (lhs, pattern, flags) => {\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n return `(${doubleStringify(pattern)}${flags ? ', ' + doubleStringify(flags) : ''})`;\n }\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate !!js/function >\n () => {\n return 'Decimal128';\n }\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate !!js/function >\n (_, str) => { // just stringify\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `.parse(\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.parse`;\n }\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate null\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate null\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # BSON Util Templates\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate !!js/function >\n () => {\n return 'new ObjectId';\n }\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate !!js/function >\n () => {\n return 'new ObjectId';\n }\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate !!js/function >\n (lhs, arg, isNumber) => {\n if (isNumber) {\n return `(new java.util.Date(${arg.replace(/L$/, '000L')}))`;\n }\n return `(${arg})`;\n }\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate !!js/function >\n () => {\n return 'ObjectId.isValid';\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg})`;\n }\n # JS Symbol Templates\n NumberSymbolTemplate: &NumberSymbolTemplate !!js/function >\n () => {\n return '';\n }\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_string') {\n return `Double.parseDouble(${arg})`;\n }\n if (type === '_integer' || type === '_long' || type === '_decimal') {\n if (arg.includes('L') || arg.includes('d')) {\n return `${arg.substr(0, arg.length - 1)}d`;\n }\n return `${arg}d`;\n }\n return `(double) ${arg}`;\n }\n DateSymbolTemplate: &DateSymbolTemplate !!js/function >\n () => {\n return 'java.util.Date';\n }\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate !!js/function >\n (lhs, date, isString) => {\n let toStr = (d) => d;\n if (isString) {\n toStr = (d) => `new SimpleDateFormat(\"EEE MMMMM dd yyyy HH:mm:ss\").format(${d})`;\n }\n if (date === null) {\n return toStr(`new ${lhs}()`);\n }\n return toStr(`new ${lhs}(${date.getTime()}L)`);\n }\n DateSymbolNowTemplate: &DateSymbolNowTemplate !!js/function >\n () => {\n return '';\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate !!js/function >\n () => {\n return 'new java.util.Date().getTime()';\n }\n RegExpSymbolTemplate: &RegExpSymbolTemplate !!js/function >\n () => {\n return 'Pattern';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null\n ImportTemplate: &ImportTemplate null\n DriverImportTemplate: &DriverImportTemplate !!js/function >\n (_, mode) => {\n let imports = 'import com.mongodb.MongoClient;\\n' +\n 'import com.mongodb.MongoClientURI;\\n' +\n 'import com.mongodb.client.MongoCollection;\\n' +\n 'import com.mongodb.client.MongoDatabase;\\n' +\n 'import org.bson.conversions.Bson;\\n' +\n 'import java.util.concurrent.TimeUnit;\\n' +\n 'import org.bson.Document;\\n';\n if (mode === 'Query') {\n imports += 'import com.mongodb.client.FindIterable;';\n } else if (mode === 'Pipeline') {\n imports += 'import com.mongodb.client.AggregateIterable;';\n } else if (mode === 'Delete Query') {\n imports += 'import com.mongodb.client.result.DeleteResult;';\n }\n return imports;\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate !!js/function >\n () => {\n return 'import java.util.regex.Pattern;';\n }\n 9ImportTemplate: &9ImportTemplate !!js/function >\n () => {\n return 'import java.util.Arrays;';\n }\n 10ImportTemplate: &10ImportTemplate !!js/function >\n () => {\n return 'import org.bson.Document;';\n }\n 11ImportTemplate: &11ImportTemplate !!js/function >\n () => {\n return 'import org.bson.BsonNull;';\n }\n 12ImportTemplate: &12ImportTemplate !!js/function >\n () => {\n return 'import org.bson.BsonUndefined;';\n }\n 100ImportTemplate: &100ImportTemplate !!js/function >\n () => {\n return 'import org.bson.types.Code;';\n }\n 113ImportTemplate: &113ImportTemplate !!js/function >\n () => {\n return 'import org.bson.types.CodeWithScope;';\n }\n 101ImportTemplate: &101ImportTemplate !!js/function >\n () => {\n return 'import org.bson.types.ObjectId;';\n }\n 102ImportTemplate: &102ImportTemplate !!js/function >\n () => {\n return 'import org.bson.types.Binary;';\n }\n 103ImportTemplate: &103ImportTemplate !!js/function >\n () => {\n return 'import com.mongodb.DBRef;';\n }\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n 107ImportTemplate: &107ImportTemplate !!js/function >\n () => {\n return 'import org.bson.types.MinKey;';\n }\n 108ImportTemplate: &108ImportTemplate !!js/function >\n () => {\n return 'import org.bson.types.MaxKey;';\n }\n 109ImportTemplate: &109ImportTemplate !!js/function >\n () => {\n return 'import org.bson.BsonRegularExpression;';\n }\n 110ImportTemplate: &110ImportTemplate !!js/function >\n () => {\n return 'import org.bson.types.BSONTimestamp;';\n }\n 111ImportTemplate: &111ImportTemplate !!js/function >\n () => {\n return 'import org.bson.types.Symbol;';\n }\n 112ImportTemplate: &112ImportTemplate !!js/function >\n () => {\n return 'import org.bson.types.Decimal128;';\n }\n 114ImportTemplate: &114ImportTemplate !!js/function >\n () => {\n return 'import org.bson.BsonBinarySubType;';\n }\n 200ImportTemplate: &200ImportTemplate null\n 201ImportTemplate: &201ImportTemplate !!js/function >\n () => {\n return 'import java.text.SimpleDateFormat;';\n }\n 300ImportTemplate: &300ImportTemplate !!js/function >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i && f !== 'options'))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Filters.${c};`;\n }).join('\\n');\n }\n 301ImportTemplate: &301ImportTemplate !!js/function >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Aggregates.${c};`;\n }).join('\\n');\n }\n 302ImportTemplate: &302ImportTemplate !!js/function >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Accumulators.${c};`;\n }).join('\\n');\n }\n 303ImportTemplate: &303ImportTemplate !!js/function >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Projections.${c};`;\n }).join('\\n');\n }\n 304ImportTemplate: &304ImportTemplate !!js/function >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Sorts.${c};`;\n }).join('\\n');\n }\n 305ImportTemplate: &305ImportTemplate !!js/function >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import com.mongodb.client.model.geojson.${c};`;\n }).join('\\n');\n }\n 306ImportTemplate: &306ImportTemplate !!js/function >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import com.mongodb.client.model.${c};`;\n }).join('\\n');\n }\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; +module.exports = + "SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n# Java Templates\nTemplates:\n # Misc\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'u'\n y: ''\n g: ''\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n # Syntax\n DriverTemplate: !!js/function &DriverTemplate >\n (spec) => {\n const comment = `/*\n * Requires the MongoDB Java Driver.\n * https://mongodb.github.io/mongo-java-driver`;\n\n const str = spec.options.uri;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n const uri = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n const exportMode = spec.exportMode;\n delete spec.exportMode;\n\n const connection = `MongoClient mongoClient = new MongoClient(\n new MongoClientURI(\n ${uri}\n )\n );\n\n MongoDatabase database = mongoClient.getDatabase(\"${spec.options.database}\");\n\n MongoCollection collection = database.getCollection(\"${spec.options.collection}\");`;\n\n let driverMethod;\n let driverResult;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'deleteMany';\n driverResult = 'DeleteResult';\n break;\n case 'Update Query':\n driverMethod = 'updateMany';\n driverResult = 'UpdateResult';\n break;\n default:\n driverMethod = 'find';\n driverResult = 'FindIterable';\n }\n if ('aggregation' in spec) {\n return `${comment}\\n */\\n\\n${connection}\n\n AggregateIterable result = collection.aggregate(${spec.aggregation});`;\n }\n\n let warning = '';\n const defs = Object.keys(spec).reduce((s, k) => {\n if (!spec[k]) return s;\n if (k === 'options' || k === 'maxTimeMS' || k === 'skip' || k === 'limit' || k === 'collation') return s;\n if (s === '') return `Bson ${k} = ${spec[k]};`;\n return `${s}\n Bson ${k} = ${spec[k]};`;\n }, '');\n\n const result = Object.keys(spec).reduce((s, k) => {\n switch (k) {\n case 'options':\n case 'filter':\n return s;\n case 'maxTimeMS':\n return `${s}\n .maxTime(${spec[k]}, TimeUnit.MICROSECONDS)`;\n case 'skip':\n case 'limit':\n return `${s}\n .${k}((int)${spec[k]})`;\n case 'project':\n return `${s}\n .projection(project)`;\n case 'collation':\n warning = '\\n *\\n * Warning: translating collation to Java not yet supported, so will be ignored';\n return s;\n case 'exportMode':\n return s;\n default:\n if (!spec[k]) return s;\n return `${s}\n .${k}(${k})`;\n }\n }, `${driverResult} result = collection.${driverMethod}(filter)`);\n\n return `${comment}${warning}\\n */\\n\\n${defs}\n\n ${connection}\n\n ${result};`;\n }\n EqualitySyntaxTemplate: !!js/function &EqualitySyntaxTemplate >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n } else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: !!js/function &InSyntaxTemplate >\n (lhs, op, rhs) => {\n let str = '';\n if (op.includes('!') || op.includes('not')) {\n str = '!';\n }\n return `${str}${rhs}.contains(${lhs})`\n }\n AndSyntaxTemplate: !!js/function &AndSyntaxTemplate >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: !!js/function &OrSyntaxTemplate >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: !!js/function &NotSyntaxTemplate >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: !!js/function &BinarySyntaxTemplate >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `floor(${s})`;\n case '**':\n return `pow(${s}, ${rhs})`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosSyntaxTemplate: &EosSyntaxTemplate null\n EofSyntaxTemplate: &EofSyntaxTemplate null\n NewTemplate: !!js/function &NewSyntaxTemplate >\n (expr, skip, code) => {\n // Add codes of classes that don't need new.\n // Currently: Decimal128/NumberDecimal, Long/NumberLong, Double, Int32, Number, regex, Date\n noNew = [112, 106, 104, 105, 2, 8, 200];\n if (skip || (code && noNew.indexOf(code) !== -1)) {\n return expr;\n }\n return `new ${expr}`;\n }\n # BSON Object Type templates\n CodeTypeTemplate: &CodeTypeTemplate null\n StringTypeTemplate: !!js/function &StringTypeTemplate >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n RegexTypeTemplate: !!js/function &RegexTypeTemplate >\n (pattern, flags) => {\n flags = flags === '' ? '' : `(?${flags})`;\n // Double escape characters except for slashes\n const escaped = pattern.replace(/\\\\/, '\\\\\\\\');\n\n // Double-quote stringify\n const str = escaped + flags;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `Pattern.compile(\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n BoolTypeTemplate: !!js/function &BoolTypeTemplate >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null\n DecimalTypeTemplate: !!js/function &DecimalTypeTemplate >\n (literal, type) => {\n if (type === '_integer' || type === '_long' || type === '_decimal') {\n return `${literal}d`;\n }\n return `(double) ${literal}`;\n }\n LongBasicTypeTemplate: !!js/function &LongBasicTypeTemplate >\n (literal, type) => {\n if (type === '_integer' || type === '_long') {\n return `${literal}L`;\n }\n return `new Long(${literal})`;\n }\n HexTypeTemplate: &HexTypeTemplate null # TODO\n OctalTypeTemplate: !!js/function &OctalTypeTemplate >\n (literal, type) => {\n if ((literal.charAt(0) === '0' && literal.charAt(1) === '0') ||\n (literal.charAt(0) === '0' && (literal.charAt(1) === 'o' || literal.charAt(1) === 'O'))) {\n return `0${literal.substr(2, literal.length - 1)}`;\n }\n return literal;\n }\n NumericTypeTemplate: &NumericTypeTemplate null\n ArrayTypeTemplate: !!js/function &ArrayTypeTemplate >\n (literal, depth) => {\n depth++;\n // TODO: figure out how to best do depth in an array and where to\n // insert and indent\n const indent = '\\n' + ' '.repeat(depth);\n // have an indent on every ', new Document' in an array not\n // entirely perfect, but at least makes this more readable/also\n // compiles\n const arr = literal.split(', new').join(`, ${indent}new`)\n\n return `Arrays.asList(${arr})`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null\n NullTypeTemplate: !!js/function &NullTypeTemplate >\n () => {\n return 'new BsonNull()';\n }\n UndefinedTypeTemplate: !!js/function &UndefinedTypeTemplate >\n () => {\n return 'new BsonUndefined()';\n }\n ObjectTypeTemplate: !!js/function &ObjectTypeTemplate >\n (literal, depth) => {\n\n if (literal === '') {\n return `new Document()`;\n }\n return literal;\n }\n ObjectTypeArgsTemplate: !!js/function &ObjectTypeArgsTemplate >\n (args, depth) => {\n if (args.length === 0) {\n return 'new Document()';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n const start = `new Document(${doubleStringify(args[0][0])}, ${args[0][1]})`;\n\n args = args.slice(1);\n const result = args.reduce((str, pair) => {\n return `${str}${indent}.append(${doubleStringify(pair[0])}, ${pair[1]})`;\n }, start);\n\n return `${result}`;\n }\n DoubleTypeTemplate: !!js/function &DoubleTypeTemplate >\n (literal, type) => {\n if (type === '_integer' || type === '_long' || type === '_decimal') {\n return `${literal}d`;\n }\n return `(double) ${literal}`;\n }\n DoubleTypeArgsTemplate: !!js/function &DoubleTypeArgsTemplate >\n () => {\n return '';\n }\n LongTypeTemplate: !!js/function &LongTemplate >\n () => {\n return '';\n }\n LongTypeArgsTemplate: &LongSymbolArgsTemplate null\n # BSON Object Method templates\n ObjectIdToStringTemplate: !!js/function &ObjectIdToStringTemplate >\n (lhs) => {\n return `${lhs}.toHexString()`;\n }\n ObjectIdToStringArgsTemplate: !!js/function &ObjectIdToStringArgsTemplate >\n () => {\n return '';\n }\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate null\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate null\n ObjectIdGetTimestampTemplate: !!js/function &ObjectIdGetTimestampTemplate >\n (lhs) => {\n return `${lhs}.getTimestamp()`;\n }\n ObjectIdGetTimestampArgsTemplate:\n !!js/function &ObjectIdGetTimestampArgsTemplate >\n () => {\n return '';\n }\n CodeCodeTemplate: !!js/function &CodeCodeTemplate >\n (lhs) => {\n return `${lhs}.getCode()`;\n }\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: !!js/function &CodeScopeTemplate >\n (lhs) => {\n return `${lhs}.getScope()`;\n }\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n BinaryValueTemplate: !!js/function &BinaryValueTemplate >\n (lhs) => {\n return `${lhs}.getData`;\n }\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: !!js/function &BinarySubtypeTemplate >\n (lhs) => {\n return `${lhs}.getType()`;\n }\n BinarySubtypeArgsTemplate: !!js/function &BinarySubtypeArgsTemplate >\n () => {\n return '';\n }\n DBRefGetDBTemplate: !!js/function &DBRefGetDBTemplate >\n (lhs) => {\n return `${lhs}.getDatabaseName()`;\n }\n DBRefGetDBArgsTemplate: !!js/function &DBRefGetDBArgsTemplate >\n () => {\n return '';\n }\n DBRefGetCollectionTemplate: !!js/function &DBRefGetCollectionTemplate >\n (lhs) => {\n return `${lhs}.getCollectionName()`;\n }\n DBRefGetCollectionArgsTemplate:\n !!js/function &DBRefGetCollectionArgsTemplate >\n () => {\n return '';\n }\n DBRefGetIdTemplate: !!js/function &DBRefGetIdTemplate >\n (lhs) => {\n return `${lhs}.getId()`;\n }\n DBRefGetIdArgsTemplate: !!js/function &DBRefGetIdArgsTemplate >\n () => {\n return '';\n }\n LongEqualsTemplate: !!js/function &LongEqualsTemplate >\n (lhs) => {\n return `${lhs} ==`;\n }\n LongEqualsArgsTemplate: !!js/function &LongEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongToStringTemplate: !!js/function &LongToStringTemplate >\n (lhs) => {\n return lhs;\n }\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToIntTemplate: !!js/function &LongToIntTemplate >\n (lhs) => {\n return `(int) ${lhs}`;\n }\n LongToIntArgsTemplate: !!js/function &LongToIntArgsTemplate >\n () => {\n return '';\n }\n LongToNumberTemplate: !!js/function &LongToNumberTemplate >\n (lhs) => {\n return `(double) ${lhs}`;\n }\n LongToNumberArgsTemplate: !!js/function &LongToNumberArgsTemplate >\n () => {\n return '';\n }\n LongAddTemplate: !!js/function &LongAddTemplate >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: !!js/function &LongAddArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: !!js/function &LongSubtractTemplate >\n (arg) => {\n return `${arg} -`;\n }\n LongSubtractArgsTemplate: !!js/function &LongSubtractArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: !!js/function &LongMultiplyTemplate >\n (arg) => {\n return `${arg} *`;\n }\n LongMultiplyArgsTemplate: !!js/function &LongMultiplyArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: !!js/function &LongDivTemplate >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: !!js/function &LongDivArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: !!js/function &LongModuloTemplate >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: !!js/function &LongModuloArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: !!js/function &LongAndTemplate >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: !!js/function &LongAndArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: !!js/function &LongOrTemplate >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: !!js/function &LongOrArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: !!js/function &LongXorTemplate >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: !!js/function &LongXorArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: !!js/function &LongShiftLeftTemplate >\n () => {\n return 'Long.rotateLeft';\n }\n LongShiftLeftArgsTemplate: !!js/function &LongShiftLeftArgsTemplate >\n (lhs, arg) => {\n return `(${lhs}, ${arg})`;\n }\n LongShiftRightTemplate: !!js/function &LongShiftRightTemplate >\n () => {\n return 'Long.rotateRight';\n }\n LongShiftRightArgsTemplate: !!js/function &LongShiftRightArgsTemplate >\n (lhs, arg) => {\n return `(${lhs}, ${arg})`;\n }\n LongCompareTemplate: !!js/function &LongCompareTemplate >\n (lhs) => {\n return `${lhs} -`;\n }\n LongCompareArgsTemplate: !!js/function &LongCompareArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongIsOddTemplate: !!js/function &LongIsOddTemplate >\n (lhs) => {\n return `(${lhs} % 2) == 1`;\n }\n LongIsOddArgsTemplate: !!js/function &LongIsOddArgsTemplate >\n () => {\n return '';\n }\n LongIsZeroTemplate: !!js/function &LongIsZeroTemplate >\n (lhs) => {\n return `${lhs} == 0`;\n }\n LongIsZeroArgsTemplate: !!js/function &LongIsZeroArgsTemplate >\n () => {\n return '';\n }\n LongIsNegativeTemplate: !!js/function &LongIsNegativeTemplate >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: !!js/function &LongIsNegativeArgsTemplate >\n () => {\n return '';\n }\n LongNegateTemplate: !!js/function &LongNegateTemplate >\n () => {\n return '-';\n }\n LongNegateArgsTemplate: !!js/function &LongNegateArgsTemplate >\n (lhs) => {\n return lhs;\n }\n LongNotTemplate: !!js/function &LongNotTemplate >\n () => {\n return '~';\n }\n LongNotArgsTemplate: !!js/function &LongNotArgsTemplate >\n (lhs) => {\n return lhs;\n }\n LongNotEqualsTemplate: !!js/function &LongNotEqualsTemplate >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: !!js/function &LongNotEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: !!js/function &LongGreaterThanTemplate >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: !!js/function &LongGreaterThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate:\n !!js/function &LongGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate:\n !!js/function &LongGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: !!js/function &LongLessThanTemplate >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: !!js/function &LongLessThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: !!js/function &LongLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate:\n !!js/function &LongLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: !!js/function &LongFloatApproxTemplate >\n (lhs) => {\n return `(float) ${lhs}`;\n }\n LongTopTemplate: !!js/function &LongTopTemplate >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: !!js/function &LongBottomTemplate >\n (lhs) => {\n return `${lhs} & 0x0000ffff`;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate null\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n TimestampEqualsTemplate: &TimestampEqualsTemplate null\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate null\n TimestampGetLowBitsTemplate: !!js/function &TimestampGetLowBitsTemplate >\n (lhs) => {\n return `${lhs}.getTime`;\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate null\n TimestampGetHighBitsTemplate: !!js/function &TimestampGetHighBitsTemplate >\n (lhs) => {\n return `${lhs}.getInc`;\n }\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate null\n TimestampTTemplate: !!js/function &TimestampTTemplate >\n (lhs) => {\n return `${lhs}.getTime()`;\n }\n TimestampITemplate: !!js/function &TimestampITemplate >\n (lhs) => {\n return `${lhs}.getInc()`;\n }\n TimestampAsDateTemplate: !!js/function &TimestampAsDateTemplate >\n (lhs) => {\n return `new java.util.Date(${lhs}.getTime())`;\n }\n TimestampAsDateArgsTemplate: !!js/function &TimestampAsDateArgsTemplate >\n () => {\n return '';\n }\n TimestampCompareTemplate: !!js/function &TimestampCompareTemplate >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate null\n TimestampNotEqualsTemplate: !!js/function &TimestampNotEqualsTemplate >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampNotEqualsArgsTemplate:\n !!js/function &TimestampNotEqualsArgsTemplate >\n (lhs, arg) => {\n return `(${arg}) != 0`;\n }\n TimestampGreaterThanTemplate: !!js/function &TimestampGreaterThanTemplate >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampGreaterThanArgsTemplate:\n !!js/function &TimestampGreaterThanArgsTemplate >\n (lhs, arg) => {\n return `(${arg}) > 0`;\n }\n TimestampGreaterThanOrEqualTemplate:\n !!js/function &TimestampGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampGreaterThanOrEqualArgsTemplate:\n !!js/function &TimestampGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return `(${arg}) >= 0`;\n }\n TimestampLessThanTemplate: !!js/function &TimestampLessThanTemplate >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampLessThanArgsTemplate: !!js/function &TimestampLessThanArgsTemplate >\n (lhs, arg) => {\n return `(${arg}) < 0`;\n }\n TimestampLessThanOrEqualTemplate:\n !!js/function &TimestampLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs}.compareTo`;\n }\n TimestampLessThanOrEqualArgsTemplate:\n !!js/function &TimestampLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return `(${arg}) <= 0`;\n }\n SymbolValueOfTemplate: !!js/function &SymbolValueOfTemplate >\n (lhs) => {\n return `${lhs}.getSymbol`;\n }\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate null\n SymbolInspectTemplate: !!js/function &SymbolInspectTemplate >\n (lhs) => {\n return `${lhs}.getSymbol`;\n }\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate null\n SymbolToStringTemplate: !!js/function &SymbolToStringTemplate >\n (lhs) => {\n return `${lhs}.toString`;\n }\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate null\n # Symbol Templates\n CodeSymbolTemplate:\n !!js/function &CodeSymbolTemplate > # Also has process method\n () => {\n return 'Code';\n }\n CodeSymbolArgsTemplate:\n !!js/function &CodeSymbolArgsTemplate > # Also has process method\n (lhs, code, scope) => {\n // Double quote stringify\n let newStr = code === undefined ? '' : code;\n const str = newStr;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n code = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n return (scope === undefined) ? `(${code})` : `WithScope(${code}, ${scope})`;\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate null\n ObjectIdSymbolArgsTemplate: !!js/function &ObjectIdSymbolArgsTemplate >\n (lhs, str) => {\n if (!str || str.length === 0) {\n return '()';\n }\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `(\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: !!js/function &BinarySymbolArgsTemplate >\n (lhs, bytes, type) => {\n const str = bytes;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n bytes = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n\n if (type === null) {\n return `(${bytes}.getBytes(\"UTF-8\"))`;\n }\n return `(${type}, ${bytes}.getBytes(\"UTF-8\"))`;\n }\n BinarySymbolSubtypeDefaultTemplate:\n !!js/function &BinarySymbolSubtypeDefaultTemplate >\n () => {\n return 'BsonBinarySubType.BINARY';\n }\n BinarySymbolSubtypeFunctionTemplate:\n !!js/function &BinarySymbolSubtypeFunctionTemplate >\n () => {\n return 'BsonBinarySubType.FUNCTION';\n }\n BinarySymbolSubtypeByteArrayTemplate:\n !!js/function &BinarySymbolSubtypeByteArrayTemplate >\n () => {\n return 'BsonBinarySubType.BINARY';\n }\n BinarySymbolSubtypeUuidOldTemplate:\n !!js/function &BinarySymbolSubtypeUuidOldTemplate >\n () => {\n return 'BsonBinarySubType.UUID_LEGACY';\n }\n BinarySymbolSubtypeUuidTemplate:\n !!js/function &BinarySymbolSubtypeUuidTemplate >\n () => {\n return 'BsonBinarySubType.UUID_STANDARD';\n }\n BinarySymbolSubtypeMd5Template:\n !!js/function &BinarySymbolSubtypeMd5Template >\n () => {\n return 'BsonBinarySubType.MD5';\n }\n BinarySymbolSubtypeUserDefinedTemplate:\n !!js/function &BinarySymbolSubtypeUserDefinedTemplate >\n () => {\n return 'BsonBinarySubType.USER_DEFINED';\n }\n DBRefSymbolTemplate: &DBRefSymbolTemplate null\n DBRefSymbolArgsTemplate: !!js/function &DBRefSymbolArgsTemplate >\n (lhs, coll, id, db) => {\n const dbstr = db === undefined ? '' : `${db}, `;\n return `(${dbstr}${coll}, ${id})`;\n }\n DoubleSymbolTemplate: !!js/function &DoubleSymbolTemplate >\n () => {\n return '';\n }\n DoubleSymbolArgsTemplate: !!js/function &DoubleSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_string') {\n return `Double.parseDouble(${arg})`;\n }\n if (type === '_integer' || type === '_long' || type === '_double' || type === '_decimal') {\n if (arg.includes('L') || arg.includes('d')) {\n return `${arg.substr(0, arg.length - 1)}d`;\n }\n return `${arg}d`;\n }\n return `(double) ${arg}`;\n }\n Int32SymbolTemplate: !!js/function &Int32SymbolTemplate >\n () => {\n return '';\n }\n Int32SymbolArgsTemplate: !!js/function &Int32SymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_string') {\n return `Integer.parseInt(${arg})`;\n }\n if (type === '_integer' || type === '_long') {\n if (arg.includes('L') || arg.includes('d')) {\n return arg.substr(0, arg.length - 1);\n }\n return arg;\n }\n return `(int) ${arg}`;\n }\n LongSymbolTemplate: !!js/function &LongSymbolTemplate >\n () => {\n return '';\n }\n LongSymbolArgsTemplate: !!js/function &LongSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_string') {\n return `Long.parseLong(${arg})`;\n }\n if (type === '_integer' || type === '_long') {\n if (arg.includes('d') || arg.includes('L')) {\n return `${arg.substr(0, arg.length - 1)}L`;\n }\n return `${arg}L`;\n }\n return `new Long(${arg})`;\n }\n LongSymbolMaxTemplate: !!js/function &LongSymbolMaxTemplate >\n () => {\n return 'Long.MAX_VALUE';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: !!js/function &LongSymbolMinTemplate >\n () => {\n return 'Long.MIN_VALUE';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: !!js/function &LongSymbolZeroTemplate >\n () => {\n return '0L';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: !!js/function &LongSymbolOneTemplate >\n () => {\n return '1L';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: !!js/function &LongSymbolNegOneTemplate >\n () => {\n return '-1L';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate:\n !!js/function &LongSymbolFromBitsTemplate > # Also has process method\n () => {\n return '';\n }\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: !!js/function &LongSymbolFromIntTemplate >\n () => {\n return '';\n }\n LongSymbolFromIntArgsTemplate: !!js/function &LongSymbolFromIntArgsTemplate >\n (lhs, arg) => {\n return `${arg}L`;\n }\n LongSymbolFromNumberTemplate: !!js/function &LongSymbolFromNumberTemplate >\n () => {\n return '';\n }\n LongSymbolFromNumberArgsTemplate:\n !!js/function &LongSymbolFromNumberArgsTemplate >\n (lhs, arg) => {\n return `${arg}L`;\n }\n LongSymbolFromStringTemplate: !!js/function &LongSymbolFromStringTemplate >\n (lhs) => {\n return `Long.parseLong`;\n }\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate null\n MinKeySymbolTemplate: &MinKeySymbolTemplate null\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate null\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate null\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate null\n TimestampSymbolTemplate: !!js/function &TimestampSymbolTemplate >\n () => {\n return 'BSONTimestamp';\n }\n TimestampSymbolArgsTemplate: !!js/function &TimestampSymbolArgsTemplate >\n (lhs, arg1, arg2) => {\n return `(${arg1 === undefined ? 0 : arg1}, ${arg2 === undefined ? 0 : arg2})`;\n }\n SymbolSymbolTemplate: !!js/function &SymbolSymbolTemplate >\n () => {\n return 'Symbol';\n }\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate null\n BSONRegExpSymbolTemplate: !!js/function &BSONRegExpSymbolTemplate >\n () => {\n return 'BsonRegularExpression';\n }\n BSONRegExpSymbolArgsTemplate: !!js/function &BSONRegExpSymbolArgsTemplate >\n (lhs, pattern, flags) => {\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n return `(${doubleStringify(pattern)}${flags ? ', ' + doubleStringify(flags) : ''})`;\n }\n Decimal128SymbolTemplate: !!js/function &Decimal128SymbolTemplate >\n () => {\n return 'Decimal128';\n }\n Decimal128SymbolArgsTemplate: !!js/function &Decimal128SymbolArgsTemplate >\n (_, str) => { // just stringify\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `.parse(\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n Decimal128SymbolFromStringTemplate:\n !!js/function &Decimal128SymbolFromStringTemplate >\n (lhs) => {\n return `${lhs}.parse`;\n }\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate null\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate null\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # BSON Util Templates\n ObjectIdCreateFromHexStringTemplate:\n !!js/function &ObjectIdCreateFromHexStringTemplate >\n () => {\n return 'new ObjectId';\n }\n ObjectIdCreateFromHexStringArgsTemplate:\n !!js/function &ObjectIdCreateFromHexStringArgsTemplate >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromTimeTemplate:\n !!js/function &ObjectIdCreateFromTimeTemplate >\n () => {\n return 'new ObjectId';\n }\n ObjectIdCreateFromTimeArgsTemplate:\n !!js/function &ObjectIdCreateFromTimeArgsTemplate >\n (lhs, arg, isNumber) => {\n if (isNumber) {\n return `(new java.util.Date(${arg.replace(/L$/, '000L')}))`;\n }\n return `(${arg})`;\n }\n ObjectIdIsValidTemplate: !!js/function &ObjectIdIsValidTemplate >\n () => {\n return 'ObjectId.isValid';\n }\n ObjectIdIsValidArgsTemplate: !!js/function &ObjectIdIsValidArgsTemplate >\n (lhs, arg) => {\n return `(${arg})`;\n }\n # JS Symbol Templates\n NumberSymbolTemplate: !!js/function &NumberSymbolTemplate >\n () => {\n return '';\n }\n NumberSymbolArgsTemplate: !!js/function &NumberSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_string') {\n return `Double.parseDouble(${arg})`;\n }\n if (type === '_integer' || type === '_long' || type === '_decimal') {\n if (arg.includes('L') || arg.includes('d')) {\n return `${arg.substr(0, arg.length - 1)}d`;\n }\n return `${arg}d`;\n }\n return `(double) ${arg}`;\n }\n DateSymbolTemplate: !!js/function &DateSymbolTemplate >\n () => {\n return 'java.util.Date';\n }\n DateSymbolArgsTemplate: !!js/function &DateSymbolArgsTemplate >\n (lhs, date, isString) => {\n let toStr = (d) => d;\n if (isString) {\n toStr = (d) => `new SimpleDateFormat(\"EEE MMMMM dd yyyy HH:mm:ss\").format(${d})`;\n }\n if (date === null) {\n return toStr(`new ${lhs}()`);\n }\n return toStr(`new ${lhs}(${date.getTime()}L)`);\n }\n DateSymbolNowTemplate: !!js/function &DateSymbolNowTemplate >\n () => {\n return '';\n }\n DateSymbolNowArgsTemplate: !!js/function &DateSymbolNowArgsTemplate >\n () => {\n return 'new java.util.Date().getTime()';\n }\n RegExpSymbolTemplate: !!js/function &RegExpSymbolTemplate >\n () => {\n return 'Pattern';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null\n ImportTemplate: &ImportTemplate null\n DriverImportTemplate: !!js/function &DriverImportTemplate >\n (_, mode) => {\n let imports = 'import com.mongodb.MongoClient;\\n' +\n 'import com.mongodb.MongoClientURI;\\n' +\n 'import com.mongodb.client.MongoCollection;\\n' +\n 'import com.mongodb.client.MongoDatabase;\\n' +\n 'import org.bson.conversions.Bson;\\n' +\n 'import java.util.concurrent.TimeUnit;\\n' +\n 'import org.bson.Document;\\n';\n if (mode === 'Query') {\n imports += 'import com.mongodb.client.FindIterable;';\n } else if (mode === 'Pipeline') {\n imports += 'import com.mongodb.client.AggregateIterable;';\n } else if (mode === 'Delete Query') {\n imports += 'import com.mongodb.client.result.DeleteResult;';\n }\n return imports;\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: !!js/function &8ImportTemplate >\n () => {\n return 'import java.util.regex.Pattern;';\n }\n 9ImportTemplate: !!js/function &9ImportTemplate >\n () => {\n return 'import java.util.Arrays;';\n }\n 10ImportTemplate: !!js/function &10ImportTemplate >\n () => {\n return 'import org.bson.Document;';\n }\n 11ImportTemplate: !!js/function &11ImportTemplate >\n () => {\n return 'import org.bson.BsonNull;';\n }\n 12ImportTemplate: !!js/function &12ImportTemplate >\n () => {\n return 'import org.bson.BsonUndefined;';\n }\n 100ImportTemplate: !!js/function &100ImportTemplate >\n () => {\n return 'import org.bson.types.Code;';\n }\n 113ImportTemplate: !!js/function &113ImportTemplate >\n () => {\n return 'import org.bson.types.CodeWithScope;';\n }\n 101ImportTemplate: !!js/function &101ImportTemplate >\n () => {\n return 'import org.bson.types.ObjectId;';\n }\n 102ImportTemplate: !!js/function &102ImportTemplate >\n () => {\n return 'import org.bson.types.Binary;';\n }\n 103ImportTemplate: !!js/function &103ImportTemplate >\n () => {\n return 'import com.mongodb.DBRef;';\n }\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n 107ImportTemplate: !!js/function &107ImportTemplate >\n () => {\n return 'import org.bson.types.MinKey;';\n }\n 108ImportTemplate: !!js/function &108ImportTemplate >\n () => {\n return 'import org.bson.types.MaxKey;';\n }\n 109ImportTemplate: !!js/function &109ImportTemplate >\n () => {\n return 'import org.bson.BsonRegularExpression;';\n }\n 110ImportTemplate: !!js/function &110ImportTemplate >\n () => {\n return 'import org.bson.types.BSONTimestamp;';\n }\n 111ImportTemplate: !!js/function &111ImportTemplate >\n () => {\n return 'import org.bson.types.Symbol;';\n }\n 112ImportTemplate: !!js/function &112ImportTemplate >\n () => {\n return 'import org.bson.types.Decimal128;';\n }\n 114ImportTemplate: !!js/function &114ImportTemplate >\n () => {\n return 'import org.bson.BsonBinarySubType;';\n }\n 200ImportTemplate: &200ImportTemplate null\n 201ImportTemplate: !!js/function &201ImportTemplate >\n () => {\n return 'import java.text.SimpleDateFormat;';\n }\n 300ImportTemplate: !!js/function &300ImportTemplate >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i && f !== 'options'))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Filters.${c};`;\n }).join('\\n');\n }\n 301ImportTemplate: !!js/function &301ImportTemplate >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Aggregates.${c};`;\n }).join('\\n');\n }\n 302ImportTemplate: !!js/function &302ImportTemplate >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Accumulators.${c};`;\n }).join('\\n');\n }\n 303ImportTemplate: !!js/function &303ImportTemplate >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Projections.${c};`;\n }).join('\\n');\n }\n 304ImportTemplate: !!js/function &304ImportTemplate >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import static com.mongodb.client.model.Sorts.${c};`;\n }).join('\\n');\n }\n 305ImportTemplate: !!js/function &305ImportTemplate >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import com.mongodb.client.model.geojson.${c};`;\n }).join('\\n');\n }\n 306ImportTemplate: !!js/function &306ImportTemplate >\n (classes) => {\n return classes\n .filter((f, i) => (classes.indexOf(f) === i))\n .sort()\n .map((c) => {\n return `import com.mongodb.client.model.${c};`;\n }).join('\\n');\n }\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; diff --git a/packages/bson-transpilers/lib/symbol-table/shelltojavascript.js b/packages/bson-transpilers/lib/symbol-table/shelltojavascript.js index eb9727c04ef..394c1f0da48 100644 --- a/packages/bson-transpilers/lib/symbol-table/shelltojavascript.js +++ b/packages/bson-transpilers/lib/symbol-table/shelltojavascript.js @@ -1 +1,2 @@ -module.exports="SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n\n# Javascript Templates\nTemplates:\n # Misc\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'u'\n y: 'y'\n g: 'g'\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n # Syntax\n DriverTemplate: &DriverTemplate !!js/function |\n (spec) => {\n const comment = `/*\n * Requires the MongoDB Node.js Driver\n * https://mongodb.github.io/node-mongodb-native\n */`;\n const translateKey = {\n project: 'projection'\n };\n\n const exportMode = spec.exportMode;\n delete spec.exportMode;\n\n const args = {};\n Object.keys(spec).forEach((k) => {\n if (k !== 'options') {\n args[k in translateKey ? translateKey[k] : k] = spec[k];\n }\n });\n\n let cmd;\n let defs;\n if (exportMode == 'Delete Query') {\n defs = `const filter = ${args.filter};\\n`;\n cmd = `const result = coll.deleteMany(filter);`;\n }\n if ('aggregation' in spec) {\n const agg = spec.aggregation;\n cmd = `const cursor = coll.aggregate(agg);\\nconst result = await cursor.toArray();`;\n defs = `const agg = ${agg};\\n`;\n } else if (!cmd) {\n let opts = '';\n\n if (Object.keys(args).length > 0) {\n defs = Object.keys(args).reduce((s, k) => {\n if (k !== 'filter') {\n if (opts === '') {\n opts = `${k}`;\n } else {\n opts = `${opts}, ${k}`;\n }\n }\n return `${s}const ${k} = ${args[k]};\\n`;\n }, '');\n opts = opts === '' ? '' : `, { ${opts} }`;\n }\n cmd = `const cursor = coll.find(filter${opts});\\nconst result = await cursor.toArray();`;\n }\n return `${comment}\\n\\n${defs}\n const client = await MongoClient.connect(\n '${spec.options.uri}'\n );\n const coll = client.db('${spec.options.database}').collection('${spec.options.collection}');\n ${cmd}\n await client.close();`;\n }\n EqualitySyntaxTemplate: &EqualitySyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} !== ${rhs}`;\n } else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} === ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: &InSyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n let str = '!==';\n if (op.includes('!') || op.includes('not')) {\n str = '===';\n }\n return `${rhs}.indexOf(${lhs}) ${str} -1`\n }\n AndSyntaxTemplate: &AndSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: &OrSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: &NotSyntaxTemplate !!js/function >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: &BinarySyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `Math.floor(${s}, ${rhs})`;\n case '**':\n return `Math.pow(${s}, ${rhs})`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosSyntaxTemplate: &EosSyntaxTemplate null\n EofSyntaxTemplate: &EofSyntaxTemplate null\n NewTemplate: &NewSyntaxTemplate !!js/function >\n (expr, skip, code) => {\n // Add classes that don't use \"new\" to array.\n // So far: [Date.now, Decimal128/NumberDecimal, Long/NumberLong]\n noNew = [200.1, 112, 106];\n if (skip || (code && noNew.indexOf(code) !== -1)) {\n return expr;\n }\n return `new ${expr}`;\n }\n # BSON Object Type templates\n CodeTypeTemplate: &CodeTypeTemplate null\n StringTypeTemplate: &StringTypeTemplate !!js/function >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n RegexTypeTemplate: &RegexTypeTemplate !!js/function >\n (pattern, flags) => {\n const str = pattern;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n pattern = `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n return `RegExp(${pattern}${flags ? ', ' + '\\'' + flags + '\\'': ''})`;\n }\n BoolTypeTemplate: &BoolTypeTemplate !!js/function >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null\n DecimalTypeTemplate: &DecimalTypeTemplate null\n LongBasicTypeTemplate: &LongBasicTypeTemplate null\n HexTypeTemplate: &HexTypeTemplate null\n OctalTypeTemplate: &OctalTypeTemplate null\n NumericTypeTemplate: &NumericTypeTemplate null\n ArrayTypeTemplate: &ArrayTypeTemplate !!js/function >\n (literal, depth) => {\n depth++;\n if (literal === '') {\n return '[]'\n }\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n\n return `[${indent}${literal}${closingIndent}]`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null\n NullTypeTemplate: &NullTypeTemplate !!js/function >\n () => {\n return 'null';\n }\n UndefinedTypeTemplate: &UndefinedTypeTemplate !!js/function >\n () => {\n return 'undefined';\n }\n ObjectTypeTemplate: &ObjectTypeTemplate !!js/function >\n (literal) => {\n if (literal === '') {\n return '{}';\n }\n return literal;\n }\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate !!js/function >\n (args, depth) => {\n if (args.length === 0) {\n return '{}';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n const pairs = args.map((arg) => {\n return `${indent}${singleStringify(arg[0])}: ${arg[1]}`;\n }).join(', ');\n\n return `{${pairs}${closingIndent}}`\n }\n # BSON Object Method templates\n CodeCodeTemplate: &CodeCodeTemplate null\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate null\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate null\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate null\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate null\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate null\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate null\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate null\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: &BinarySubtypeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.sub_type`;\n }\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetDBTemplate: &DBRefGetDBTemplate !!js/function >\n (lhs) => {\n return `${lhs}.db`;\n }\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate !!js/function >\n (lhs) => {\n return `${lhs}.namespace`;\n }\n DBRefGetIdTemplate: &DBRefGetIdTemplate !!js/function >\n (lhs) => {\n return `${lhs}.oid`;\n }\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongEqualsTemplate: &LongEqualsTemplate null\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate null\n LongToStringTemplate: &LongToStringTemplate null\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToIntTemplate: &LongToIntTemplate !!js/function >\n (lhs) => {\n return `${lhs}.toInt`;\n }\n LongToIntArgsTemplate: &LongToIntArgsTemplate null\n LongToNumberTemplate: &LongToNumberTemplate null\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate null\n LongAddTemplate: &LongAddTemplate null\n LongAddArgsTemplate: &LongAddArgsTemplate null\n LongSubtractTemplate: &LongSubtractTemplate null\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate null\n LongMultiplyTemplate: &LongMultiplyTemplate null\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate null\n LongDivTemplate: &LongDivTemplate null\n LongDivArgsTemplate: &LongDivArgsTemplate null\n LongModuloTemplate: &LongModuloTemplate null\n LongModuloArgsTemplate: &LongModuloArgsTemplate null\n LongAndTemplate: &LongAndTemplate null\n LongAndArgsTemplate: &LongAndArgsTemplate null\n LongOrTemplate: &LongOrTemplate null\n LongOrArgsTemplate: &LongOrArgsTemplate null\n LongXorTemplate: &LongXorTemplate null\n LongXorArgsTemplate: &LongXorArgsTemplate null\n LongShiftLeftTemplate: &LongShiftLeftTemplate null\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate null\n LongShiftRightTemplate: &LongShiftRightTemplate null\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate null\n LongCompareTemplate: &LongCompareTemplate null\n LongCompareArgsTemplate: &LongCompareArgsTemplate null\n LongIsOddTemplate: &LongIsOddTemplate null\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate null\n LongIsZeroTemplate: &LongIsZeroTemplate null\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate null\n LongIsNegativeTemplate: &LongIsNegativeTemplate null\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate null\n LongNegateTemplate: &LongNegateTemplate null\n LongNegateArgsTemplate: &LongNegateArgsTemplate null\n LongNotTemplate: &LongNotTemplate null\n LongNotArgsTemplate: &LongNotArgsTemplate null\n LongNotEqualsTemplate: &LongNotEqualsTemplate null\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate null\n LongGreaterThanTemplate: &LongGreaterThanTemplate null\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate null\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate null\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate null\n LongLessThanTemplate: &LongLessThanTemplate null\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate null\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate null\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate null\n LongFloatApproxTemplate: &LongFloatApproxTemplate !!js/function >\n (lhs) => {\n return `${lhs}.toNumber()`;\n }\n LongTopTemplate: &LongTopTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getHighBits()`;\n }\n LongBottomTemplate: &LongBottomTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getLowBits()`;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate null\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n TimestampEqualsTemplate: &TimestampEqualsTemplate null\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate null\n TimestampGetLowBitsTemplate: &TimestampGetLowBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getLowBits`;\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate null\n TimestampGetHighBitsTemplate: &TimestampGetHighBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getHighBits`;\n }\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate null\n TimestampTTemplate: &TimestampTTemplate !!js/function >\n (lhs) => {\n return `${lhs}.getLowBits()`;\n }\n TimestampITemplate: &TimestampITemplate !!js/function >\n (lhs) => {\n return `${lhs}.getHighBits()`;\n }\n TimestampAsDateTemplate: &TimestampAsDateTemplate !!js/function >\n (lhs) => {\n return `new Date(${lhs}.getHighBits() * 1000)`;\n }\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate !!js/function >\n () => {\n return '';\n }\n TimestampCompareTemplate: &TimestampCompareTemplate null\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate null\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate null\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate null\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate null\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate null\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate null\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate null\n TimestampLessThanTemplate: &TimestampLessThanTemplate null\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate null\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate null\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate null\n SymbolValueOfTemplate: &SymbolValueOfTemplate null\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate null\n SymbolInspectTemplate: &SymbolInspectTemplate null\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate null\n SymbolToStringTemplate: &SymbolToStringTemplate null\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate null\n # Symbol Templates\n CodeSymbolTemplate: &CodeSymbolTemplate null\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate !!js/function >\n (lhs, code, scope) => {\n code = code === undefined ? '\\'\\'' : code;\n scope = scope === undefined ? '' : `, ${scope}`;\n return `(${code}${scope})`;\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate null\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate !!js/function >\n (lhs, str) => {\n if (!str || str.length === 0) {\n return '()';\n }\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `('${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}')`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate !!js/function >\n () => {\n return 'Binary';\n }\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate !!js/function >\n (lhs, buffer, subtype) => {\n return `(${buffer.toString('base64')}, '${subtype}')`;\n }\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate null\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate null\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate null\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate null\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate null\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template null\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate null\n DBRefSymbolTemplate: &DBRefSymbolTemplate null\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null\n DoubleSymbolTemplate: &DoubleSymbolTemplate !!js/function >\n () => {\n return 'Double';\n }\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate null\n Int32SymbolTemplate: &Int32SymbolTemplate !!js/function >\n () => {\n return 'Int32';\n }\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n arg = arg === undefined ? 0 : arg;\n return `(${arg})`;\n }\n LongSymbolTemplate: &LongSymbolTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_string') {\n return `Long.fromString(${arg})`;\n }\n return `Long.fromNumber(${arg})`;\n }\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate null\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate null\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate null\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate null\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate null\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate null\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate null\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate null\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate null\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate null\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate null\n MinKeySymbolTemplate: &MinKeySymbolTemplate null\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate null\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate null\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate null\n TimestampSymbolTemplate: &TimestampSymbolTemplate null\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate !!js/function >\n (lhs, arg1, arg2) => {\n return `(${arg1 === undefined ? 0 : arg1}, ${arg2 === undefined ? 0 : arg2})`;\n }\n SymbolSymbolTemplate: &SymbolSymbolTemplate !!js/function >\n () => {\n return 'BSONSymbol';\n }\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate null\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate !!js/function >\n () => {\n return 'BSONRegExp';\n }\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate !!js/function >\n (lhs, pattern, flags) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}'`;\n }\n return `(${singleStringify(pattern)}${flags ? ', ' + singleStringify(flags) : ''})`;\n }\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate !!js/function >\n () => {\n return 'Decimal128';\n }\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n arg = arg === undefined ? '0' : arg.toString();\n if (arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'') {\n return `.fromString(${arg})`;\n }\n return `.fromString('${arg}')`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate null\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate null\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate null\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # BSON Util Templates\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate null\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate null\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate !!js/function >\n () => {\n return `ObjectId.createFromTime`;\n }\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate !!js/function >\n (lhs, arg, isNumber) => {\n if (!isNumber) {\n return `(${arg}.getTime() / 1000)`;\n }\n return `(${arg})`;\n }\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate !!js/function >\n (lhs) => {\n return `${lhs}.isValid`;\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n # JS Symbol Templates\n NumberSymbolTemplate: &NumberSymbolTemplate !!js/function >\n () => {\n return 'Number';\n }\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n arg = arg === undefined ? '0' : arg;\n return `(${arg})`;\n }\n DateSymbolTemplate: &DateSymbolTemplate !!js/function >\n () => {\n return 'Date';\n }\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate null\n DateSymbolNowTemplate: &DateSymbolNowTemplate !!js/function >\n () => {\n return 'Date.now';\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate null\n RegExpSymbolTemplate: &RegExpSymbolTemplate !!js/function >\n () => {\n return 'RegExp';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null\n ImportTemplate: &ImportTemplate !!js/function >\n (args) => {\n const bson = [];\n const other = [];\n Object.keys(args).map(\n (m) => {\n if (m > 99 && m < 200) {\n bson.push(args[m]);\n } else {\n other.push(args[m]);\n }\n }\n );\n if (bson.length) {\n other.push(`import {\\n ${bson.join(',\\n ')}\\n} from 'mongodb';`);\n }\n return other.join('\\n');\n }\n DriverImportTemplate: &DriverImportTemplate !!js/function >\n () => {\n return `import { MongoClient } from 'mongodb';`;\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate null\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: &100ImportTemplate !!js/function >\n () => {\n return 'Code';\n }\n 101ImportTemplate: &101ImportTemplate !!js/function >\n () => {\n return 'ObjectId';\n }\n 102ImportTemplate: &102ImportTemplate !!js/function >\n () => {\n return 'Binary';\n }\n 103ImportTemplate: &103ImportTemplate !!js/function >\n () => {\n return 'DBRef';\n }\n 104ImportTemplate: &104ImportTemplate !!js/function >\n () => {\n return 'Double';\n }\n 105ImportTemplate: &105ImportTemplate !!js/function >\n () => {\n return 'Int32';\n }\n 106ImportTemplate: &106ImportTemplate !!js/function >\n () => {\n return 'Long';\n }\n 107ImportTemplate: &107ImportTemplate !!js/function >\n () => {\n return 'MinKey';\n }\n 108ImportTemplate: &108ImportTemplate !!js/function >\n () => {\n return 'MaxKey';\n }\n 109ImportTemplate: &109ImportTemplate !!js/function >\n () => {\n return 'BSONRegExp';\n }\n 110ImportTemplate: &110ImportTemplate !!js/function >\n () => {\n return 'Timestamp';\n }\n 111ImportTemplate: &111ImportTemplate !!js/function >\n () => {\n return 'BSONSymbol';\n }\n 112ImportTemplate: &112ImportTemplate !!js/function >\n () => {\n return 'Decimal128';\n }\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate null\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; +module.exports = + 'SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n# Javascript Templates\nTemplates:\n # Misc\n RegexFlags: &RegexFlags\n i: \'i\'\n m: \'m\'\n u: \'u\'\n y: \'y\'\n g: \'g\'\n BSONRegexFlags: &BSONRegexFlags\n i: \'i\'\n m: \'m\'\n x: \'x\'\n s: \'s\'\n l: \'l\'\n u: \'u\'\n # Syntax\n DriverTemplate: !!js/function &DriverTemplate |\n (spec) => {\n const comment = `/*\n * Requires the MongoDB Node.js Driver\n * https://mongodb.github.io/node-mongodb-native\n */`;\n const translateKey = {\n project: \'projection\'\n };\n\n const exportMode = spec.exportMode;\n delete spec.exportMode;\n\n const args = {};\n Object.keys(spec).forEach((k) => {\n if (k !== \'options\') {\n args[k in translateKey ? translateKey[k] : k] = spec[k];\n }\n });\n\n let cmd;\n let defs;\n if (exportMode == \'Delete Query\') {\n defs = `const filter = ${args.filter};\\n`;\n cmd = `const result = coll.deleteMany(filter);`;\n }\n if (\'aggregation\' in spec) {\n const agg = spec.aggregation;\n cmd = `const cursor = coll.aggregate(agg);\\nconst result = await cursor.toArray();`;\n defs = `const agg = ${agg};\\n`;\n } else if (!cmd) {\n let opts = \'\';\n\n if (Object.keys(args).length > 0) {\n defs = Object.keys(args).reduce((s, k) => {\n if (k !== \'filter\') {\n if (opts === \'\') {\n opts = `${k}`;\n } else {\n opts = `${opts}, ${k}`;\n }\n }\n return `${s}const ${k} = ${args[k]};\\n`;\n }, \'\');\n opts = opts === \'\' ? \'\' : `, { ${opts} }`;\n }\n cmd = `const cursor = coll.find(filter${opts});\\nconst result = await cursor.toArray();`;\n }\n return `${comment}\\n\\n${defs}\n const client = await MongoClient.connect(\n \'${spec.options.uri}\'\n );\n const coll = client.db(\'${spec.options.database}\').collection(\'${spec.options.collection}\');\n ${cmd}\n await client.close();`;\n }\n EqualitySyntaxTemplate: !!js/function &EqualitySyntaxTemplate >\n (lhs, op, rhs) => {\n if (op.includes(\'!\') || op.includes(\'not\')) {\n return `${lhs} !== ${rhs}`;\n } else if (op === \'==\' || op === \'===\' || op === \'is\') {\n return `${lhs} === ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: !!js/function &InSyntaxTemplate >\n (lhs, op, rhs) => {\n let str = \'!==\';\n if (op.includes(\'!\') || op.includes(\'not\')) {\n str = \'===\';\n }\n return `${rhs}.indexOf(${lhs}) ${str} -1`\n }\n AndSyntaxTemplate: !!js/function &AndSyntaxTemplate >\n (args) => {\n return args.join(\' && \');\n }\n OrSyntaxTemplate: !!js/function &OrSyntaxTemplate >\n (args) => {\n return args.join(\' || \');\n }\n NotSyntaxTemplate: !!js/function &NotSyntaxTemplate >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: !!js/function &BinarySyntaxTemplate >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case \'//\':\n return `Math.floor(${s}, ${rhs})`;\n case \'**\':\n return `Math.pow(${s}, ${rhs})`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosSyntaxTemplate: &EosSyntaxTemplate null\n EofSyntaxTemplate: &EofSyntaxTemplate null\n NewTemplate: !!js/function &NewSyntaxTemplate >\n (expr, skip, code) => {\n // Add classes that don\'t use "new" to array.\n // So far: [Date.now, Decimal128/NumberDecimal, Long/NumberLong]\n noNew = [200.1, 112, 106];\n if (skip || (code && noNew.indexOf(code) !== -1)) {\n return expr;\n }\n return `new ${expr}`;\n }\n # BSON Object Type templates\n CodeTypeTemplate: &CodeTypeTemplate null\n StringTypeTemplate: !!js/function &StringTypeTemplate >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\'${newStr.replace(/\\\\([\\s\\S])|(\')/g, \'\\\\$1$2\')}\'`;\n }\n RegexTypeTemplate: !!js/function &RegexTypeTemplate >\n (pattern, flags) => {\n const str = pattern;\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n pattern = `\'${newStr.replace(/\\\\([\\s\\S])|(\')/g, \'\\\\$1$2\')}\'`;\n return `RegExp(${pattern}${flags ? \', \' + \'\\\'\' + flags + \'\\\'\': \'\'})`;\n }\n BoolTypeTemplate: !!js/function &BoolTypeTemplate >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null\n DecimalTypeTemplate: &DecimalTypeTemplate null\n LongBasicTypeTemplate: &LongBasicTypeTemplate null\n HexTypeTemplate: &HexTypeTemplate null\n OctalTypeTemplate: &OctalTypeTemplate null\n NumericTypeTemplate: &NumericTypeTemplate null\n ArrayTypeTemplate: !!js/function &ArrayTypeTemplate >\n (literal, depth) => {\n depth++;\n if (literal === \'\') {\n return \'[]\'\n }\n const indent = \'\\n\' + \' \'.repeat(depth);\n const closingIndent = \'\\n\' + \' \'.repeat(depth - 1);\n\n return `[${indent}${literal}${closingIndent}]`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null\n NullTypeTemplate: !!js/function &NullTypeTemplate >\n () => {\n return \'null\';\n }\n UndefinedTypeTemplate: !!js/function &UndefinedTypeTemplate >\n () => {\n return \'undefined\';\n }\n ObjectTypeTemplate: !!js/function &ObjectTypeTemplate >\n (literal) => {\n if (literal === \'\') {\n return \'{}\';\n }\n return literal;\n }\n ObjectTypeArgsTemplate: !!js/function &ObjectTypeArgsTemplate >\n (args, depth) => {\n if (args.length === 0) {\n return \'{}\';\n }\n depth++;\n const indent = \'\\n\' + \' \'.repeat(depth);\n const closingIndent = \'\\n\' + \' \'.repeat(depth - 1);\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\'${newStr.replace(/\\\\([\\s\\S])|(\')/g, \'\\\\$1$2\')}\'`;\n }\n const pairs = args.map((arg) => {\n return `${indent}${singleStringify(arg[0])}: ${arg[1]}`;\n }).join(\', \');\n\n return `{${pairs}${closingIndent}}`\n }\n # BSON Object Method templates\n CodeCodeTemplate: &CodeCodeTemplate null\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate null\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate null\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate null\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate null\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate null\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate null\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate null\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: !!js/function &BinarySubtypeTemplate >\n (lhs) => {\n return `${lhs}.sub_type`;\n }\n BinarySubtypeArgsTemplate: !!js/function &BinarySubtypeArgsTemplate >\n () => {\n return \'\';\n }\n DBRefGetDBTemplate: !!js/function &DBRefGetDBTemplate >\n (lhs) => {\n return `${lhs}.db`;\n }\n DBRefGetCollectionTemplate: !!js/function &DBRefGetCollectionTemplate >\n (lhs) => {\n return `${lhs}.namespace`;\n }\n DBRefGetIdTemplate: !!js/function &DBRefGetIdTemplate >\n (lhs) => {\n return `${lhs}.oid`;\n }\n DBRefGetDBArgsTemplate: !!js/function &DBRefGetDBArgsTemplate >\n () => {\n return \'\';\n }\n DBRefGetCollectionArgsTemplate:\n !!js/function &DBRefGetCollectionArgsTemplate >\n () => {\n return \'\';\n }\n DBRefGetIdArgsTemplate: !!js/function &DBRefGetIdArgsTemplate >\n () => {\n return \'\';\n }\n LongEqualsTemplate: &LongEqualsTemplate null\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate null\n LongToStringTemplate: &LongToStringTemplate null\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToIntTemplate: !!js/function &LongToIntTemplate >\n (lhs) => {\n return `${lhs}.toInt`;\n }\n LongToIntArgsTemplate: &LongToIntArgsTemplate null\n LongToNumberTemplate: &LongToNumberTemplate null\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate null\n LongAddTemplate: &LongAddTemplate null\n LongAddArgsTemplate: &LongAddArgsTemplate null\n LongSubtractTemplate: &LongSubtractTemplate null\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate null\n LongMultiplyTemplate: &LongMultiplyTemplate null\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate null\n LongDivTemplate: &LongDivTemplate null\n LongDivArgsTemplate: &LongDivArgsTemplate null\n LongModuloTemplate: &LongModuloTemplate null\n LongModuloArgsTemplate: &LongModuloArgsTemplate null\n LongAndTemplate: &LongAndTemplate null\n LongAndArgsTemplate: &LongAndArgsTemplate null\n LongOrTemplate: &LongOrTemplate null\n LongOrArgsTemplate: &LongOrArgsTemplate null\n LongXorTemplate: &LongXorTemplate null\n LongXorArgsTemplate: &LongXorArgsTemplate null\n LongShiftLeftTemplate: &LongShiftLeftTemplate null\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate null\n LongShiftRightTemplate: &LongShiftRightTemplate null\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate null\n LongCompareTemplate: &LongCompareTemplate null\n LongCompareArgsTemplate: &LongCompareArgsTemplate null\n LongIsOddTemplate: &LongIsOddTemplate null\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate null\n LongIsZeroTemplate: &LongIsZeroTemplate null\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate null\n LongIsNegativeTemplate: &LongIsNegativeTemplate null\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate null\n LongNegateTemplate: &LongNegateTemplate null\n LongNegateArgsTemplate: &LongNegateArgsTemplate null\n LongNotTemplate: &LongNotTemplate null\n LongNotArgsTemplate: &LongNotArgsTemplate null\n LongNotEqualsTemplate: &LongNotEqualsTemplate null\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate null\n LongGreaterThanTemplate: &LongGreaterThanTemplate null\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate null\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate null\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate null\n LongLessThanTemplate: &LongLessThanTemplate null\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate null\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate null\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate null\n LongFloatApproxTemplate: !!js/function &LongFloatApproxTemplate >\n (lhs) => {\n return `${lhs}.toNumber()`;\n }\n LongTopTemplate: !!js/function &LongTopTemplate >\n (lhs) => {\n return `${lhs}.getHighBits()`;\n }\n LongBottomTemplate: !!js/function &LongBottomTemplate >\n (lhs) => {\n return `${lhs}.getLowBits()`;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate null\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n TimestampEqualsTemplate: &TimestampEqualsTemplate null\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate null\n TimestampGetLowBitsTemplate: !!js/function &TimestampGetLowBitsTemplate >\n (lhs) => {\n return `${lhs}.getLowBits`;\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate null\n TimestampGetHighBitsTemplate: !!js/function &TimestampGetHighBitsTemplate >\n (lhs) => {\n return `${lhs}.getHighBits`;\n }\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate null\n TimestampTTemplate: !!js/function &TimestampTTemplate >\n (lhs) => {\n return `${lhs}.getLowBits()`;\n }\n TimestampITemplate: !!js/function &TimestampITemplate >\n (lhs) => {\n return `${lhs}.getHighBits()`;\n }\n TimestampAsDateTemplate: !!js/function &TimestampAsDateTemplate >\n (lhs) => {\n return `new Date(${lhs}.getHighBits() * 1000)`;\n }\n TimestampAsDateArgsTemplate: !!js/function &TimestampAsDateArgsTemplate >\n () => {\n return \'\';\n }\n TimestampCompareTemplate: &TimestampCompareTemplate null\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate null\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate null\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate null\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate null\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate null\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate null\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate null\n TimestampLessThanTemplate: &TimestampLessThanTemplate null\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate null\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate null\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate null\n SymbolValueOfTemplate: &SymbolValueOfTemplate null\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate null\n SymbolInspectTemplate: &SymbolInspectTemplate null\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate null\n SymbolToStringTemplate: &SymbolToStringTemplate null\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate null\n # Symbol Templates\n CodeSymbolTemplate: &CodeSymbolTemplate null\n CodeSymbolArgsTemplate: !!js/function &CodeSymbolArgsTemplate >\n (lhs, code, scope) => {\n code = code === undefined ? \'\\\'\\\'\' : code;\n scope = scope === undefined ? \'\' : `, ${scope}`;\n return `(${code}${scope})`;\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate null\n ObjectIdSymbolArgsTemplate: !!js/function &ObjectIdSymbolArgsTemplate >\n (lhs, str) => {\n if (!str || str.length === 0) {\n return \'()\';\n }\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `(\'${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}\')`;\n }\n BinarySymbolTemplate: !!js/function &BinarySymbolTemplate >\n () => {\n return \'Binary\';\n }\n BinarySymbolArgsTemplate: !!js/function &BinarySymbolArgsTemplate >\n (lhs, buffer, subtype) => {\n return `(${buffer.toString(\'base64\')}, \'${subtype}\')`;\n }\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate null\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate null\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate null\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate null\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate null\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template null\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate null\n DBRefSymbolTemplate: &DBRefSymbolTemplate null\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null\n DoubleSymbolTemplate: !!js/function &DoubleSymbolTemplate >\n () => {\n return \'Double\';\n }\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate null\n Int32SymbolTemplate: !!js/function &Int32SymbolTemplate >\n () => {\n return \'Int32\';\n }\n Int32SymbolArgsTemplate: !!js/function &Int32SymbolArgsTemplate >\n (lhs, arg) => {\n arg = arg === undefined ? 0 : arg;\n return `(${arg})`;\n }\n LongSymbolTemplate: !!js/function &LongSymbolTemplate >\n () => {\n return \'\';\n }\n LongSymbolArgsTemplate: !!js/function &LongSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === \'_string\') {\n return `Long.fromString(${arg})`;\n }\n return `Long.fromNumber(${arg})`;\n }\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate null\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate null\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate null\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate null\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate null\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate null\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate null\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate null\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate null\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate null\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate null\n MinKeySymbolTemplate: &MinKeySymbolTemplate null\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate null\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate null\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate null\n TimestampSymbolTemplate: &TimestampSymbolTemplate null\n TimestampSymbolArgsTemplate: !!js/function &TimestampSymbolArgsTemplate >\n (lhs, arg1, arg2) => {\n return `(${arg1 === undefined ? 0 : arg1}, ${arg2 === undefined ? 0 : arg2})`;\n }\n SymbolSymbolTemplate: !!js/function &SymbolSymbolTemplate >\n () => {\n return \'BSONSymbol\';\n }\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate null\n BSONRegExpSymbolTemplate: !!js/function &BSONRegExpSymbolTemplate >\n () => {\n return \'BSONRegExp\';\n }\n BSONRegExpSymbolArgsTemplate: !!js/function &BSONRegExpSymbolArgsTemplate >\n (lhs, pattern, flags) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === \'\\\'\' && str.charAt(str.length - 1) === \'\\\'\') ||\n (str.charAt(0) === \'"\' && str.charAt(str.length - 1) === \'"\')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\'${newStr.replace(/\\\\([\\s\\S])|(")/g, \'\\\\$1$2\')}\'`;\n }\n return `(${singleStringify(pattern)}${flags ? \', \' + singleStringify(flags) : \'\'})`;\n }\n Decimal128SymbolTemplate: !!js/function &Decimal128SymbolTemplate >\n () => {\n return \'Decimal128\';\n }\n Decimal128SymbolArgsTemplate: !!js/function &Decimal128SymbolArgsTemplate >\n (lhs, arg) => {\n arg = arg === undefined ? \'0\' : arg.toString();\n if (arg.charAt(0) === \'\\\'\' && arg.charAt(arg.length - 1) === \'\\\'\') {\n return `.fromString(${arg})`;\n }\n return `.fromString(\'${arg}\')`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate null\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate null\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate null\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # BSON Util Templates\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate null\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate null\n ObjectIdCreateFromTimeTemplate:\n !!js/function &ObjectIdCreateFromTimeTemplate >\n () => {\n return `ObjectId.createFromTime`;\n }\n ObjectIdCreateFromTimeArgsTemplate:\n !!js/function &ObjectIdCreateFromTimeArgsTemplate >\n (lhs, arg, isNumber) => {\n if (!isNumber) {\n return `(${arg}.getTime() / 1000)`;\n }\n return `(${arg})`;\n }\n ObjectIdIsValidTemplate: !!js/function &ObjectIdIsValidTemplate >\n (lhs) => {\n return `${lhs}.isValid`;\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n # JS Symbol Templates\n NumberSymbolTemplate: !!js/function &NumberSymbolTemplate >\n () => {\n return \'Number\';\n }\n NumberSymbolArgsTemplate: !!js/function &NumberSymbolArgsTemplate >\n (lhs, arg) => {\n arg = arg === undefined ? \'0\' : arg;\n return `(${arg})`;\n }\n DateSymbolTemplate: !!js/function &DateSymbolTemplate >\n () => {\n return \'Date\';\n }\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate null\n DateSymbolNowTemplate: !!js/function &DateSymbolNowTemplate >\n () => {\n return \'Date.now\';\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate null\n RegExpSymbolTemplate: !!js/function &RegExpSymbolTemplate >\n () => {\n return \'RegExp\';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null\n ImportTemplate: !!js/function &ImportTemplate >\n (args) => {\n const bson = [];\n const other = [];\n Object.keys(args).map(\n (m) => {\n if (m > 99 && m < 200) {\n bson.push(args[m]);\n } else {\n other.push(args[m]);\n }\n }\n );\n if (bson.length) {\n other.push(`import {\\n ${bson.join(\',\\n \')}\\n} from \'mongodb\';`);\n }\n return other.join(\'\\n\');\n }\n DriverImportTemplate: !!js/function &DriverImportTemplate >\n () => {\n return `import { MongoClient } from \'mongodb\';`;\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate null\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: !!js/function &100ImportTemplate >\n () => {\n return \'Code\';\n }\n 101ImportTemplate: !!js/function &101ImportTemplate >\n () => {\n return \'ObjectId\';\n }\n 102ImportTemplate: !!js/function &102ImportTemplate >\n () => {\n return \'Binary\';\n }\n 103ImportTemplate: !!js/function &103ImportTemplate >\n () => {\n return \'DBRef\';\n }\n 104ImportTemplate: !!js/function &104ImportTemplate >\n () => {\n return \'Double\';\n }\n 105ImportTemplate: !!js/function &105ImportTemplate >\n () => {\n return \'Int32\';\n }\n 106ImportTemplate: !!js/function &106ImportTemplate >\n () => {\n return \'Long\';\n }\n 107ImportTemplate: !!js/function &107ImportTemplate >\n () => {\n return \'MinKey\';\n }\n 108ImportTemplate: !!js/function &108ImportTemplate >\n () => {\n return \'MaxKey\';\n }\n 109ImportTemplate: !!js/function &109ImportTemplate >\n () => {\n return \'BSONRegExp\';\n }\n 110ImportTemplate: !!js/function &110ImportTemplate >\n () => {\n return \'Timestamp\';\n }\n 111ImportTemplate: !!js/function &111ImportTemplate >\n () => {\n return \'BSONSymbol\';\n }\n 112ImportTemplate: !!js/function &112ImportTemplate >\n () => {\n return \'Decimal128\';\n }\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate null\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven\'t implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: "_bool"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: "_integer"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: "_long"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: "_decimal"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: "_hex"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: "_octal"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: "_numeric"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: "_string"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: "_regex"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: "_array"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: "_object"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: "_null"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: "_undefined"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn\'t add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren\'t defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: "Code"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: "code"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: "scope"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: "ObjectId"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: "equals"\n args:\n - [ "ObjectId" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: "getTimestamp"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: "BinData"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: "base64"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: "length"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: "subtype"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: "DBRef"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: "getDb"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: "$db"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: "getCollection"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: "getRef"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: "$ref"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: "getId"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: "$id"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: "NumberInt"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: "NumberLong"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "LongtoString" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: "equals"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: "toInt"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: "toNumber"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: "compare"\n args:\n - [ "Long" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: "isOdd"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: "isZero"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: "isNegative"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: "negate"\n type: "Long"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: "not"\n type: "Long"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: "notEquals"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: "greaterThan"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: "greaterThanOrEqual"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: "lessThan"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: "lessThanOrEqual"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: "add"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: "subtract"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: "multiply"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: "div"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: "modulo"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: "and"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: "or"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: "xor"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: "shiftLeft"\n args:\n - [ *IntegerType ]\n type: "Long"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: "shiftRight"\n args:\n - [ *IntegerType ]\n type: "Long"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: "MinKey"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: "MaxKey"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: "Timestamp"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: "equals"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: "getLowBits"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: "getHighBits"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: "compare"\n args:\n - [ "Timestamp" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: "notEquals"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: "greaterThan"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: "greaterThanOrEqual"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: "lessThan"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: "lessThanOrEqual"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: "BSONSymbol"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: "valueOf"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: "inspect"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: "Double"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: "Decimal128"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: "NumberDecimal"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: "SUBTYPE_DEFAULT"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: "SUBTYPE_FUNCTION"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: "SUBTYPE_BYTE_ARRAY"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: "SUBTYPE_UUID_OLD"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: "SUBTYPE_UUID"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: "SUBTYPE_MD5"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: "SUBTYPE_USER_DEFINED"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: "BSONRegExp"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: "Date"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: "RegExp"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: "Code"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: "ObjectId"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: "createFromHexString"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: "ObjectIdCreateFromTime"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: "isValid"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: "BinData"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: "DBRef"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: "Int32"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: "NumberLong"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: "MinKey"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: "MaxKey"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: "Timestamp"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: "Symbol"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: "NumberDecimal"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: "BSONRegExp"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: "BSONSymbol"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: "Decimal128"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: "fromString"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: "Double"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: "Int32"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: "Long"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: "MAX_VALUE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: "MIN_VALUE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: "ZERO"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: "ONE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: "NEG_ONE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: "LongfromBits" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: "fromInt"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: "fromNumber"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: "fromString"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: "Number"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: "Date"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: "now"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: "ISODate"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: "now"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: "RegExp"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n'; diff --git a/packages/bson-transpilers/lib/symbol-table/shelltoobject.js b/packages/bson-transpilers/lib/symbol-table/shelltoobject.js index 495bc67dcdb..dec18be1304 100644 --- a/packages/bson-transpilers/lib/symbol-table/shelltoobject.js +++ b/packages/bson-transpilers/lib/symbol-table/shelltoobject.js @@ -1 +1,2 @@ -module.exports="SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace 'null' with '!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'u'\n y: 'y'\n g: 'g'\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: &DriverTemplate null\n EqualitySyntaxTemplate: &EqualitySyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n return lhs !== rhs;\n }\n if (op === '==' || op === '===' || op === 'is') {\n if (typeof(lhs) === 'object' && 'equals' in lhs) {\n // Use '.equals' for objects, if it exists.\n return lhs.equals(rhs);\n }\n return lhs === rhs;\n }\n if (op === '>') {\n return lhs > rhs;\n }\n if (op === '<') {\n return lhs < rhs;\n }\n if (op === '>=') {\n return lhs >= rhs;\n }\n if (op === '<=') {\n return lhs <= rhs;\n }\n throw new Error(`unrecognized operation: ${op}`);\n }\n InSyntaxTemplate: &InSyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n if (typeof rhs === 'array') {\n return rhs.indexOf(lhs) === -1;\n }\n return !(lhs in rhs);\n }\n if (typeof rhs === 'array') {\n return rhs.indexOf(lhs) !== -1;\n }\n return lhs in rhs;\n }\n\n AndSyntaxTemplate: &AndSyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((t, k, i) => {\n return t && k;\n });\n }\n OrSyntaxTemplate: &OrSyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((t, k, i) => {\n return t || k;\n });\n }\n NotSyntaxTemplate: &NotSyntaxTemplate !!js/function >\n (arg) => {\n return !arg;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate !!js/function >\n (op, arg) => {\n switch(op) {\n case '+':\n return +arg;\n case '-':\n return -arg;\n case '~':\n return ~arg;\n default:\n throw new Error(`unrecognized operation: ${op}`);\n }\n }\n BinarySyntaxTemplate: &BinarySyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '+':\n return s + rhs;\n case '-':\n return s - rhs;\n case '*':\n return s * rhs;\n case '/':\n return s / rhs;\n case '**':\n return Math.pow(s, rhs);\n case '//':\n return Math.floor(s, rhs);\n case '%':\n return s % rhs;\n case '>>':\n return s >> rhs;\n case '<<':\n return s << rhs;\n case '|':\n return s | rhs;\n case '&':\n return s & rhs;\n case '^':\n return s ^ rhs;\n default:\n throw new Error(`unrecognized operation: ${op}`);\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate !!js/function >\n (arg) => {\n return arg;\n }\n EosSyntaxTemplate: &EosSyntaxTemplate !!js/function >\n () => {\n return 'a unique thing';\n }\n EofSyntaxTemplate: &EofSyntaxTemplate !!js/function >\n () => {\n return 'a unique thing';\n }\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: &StringTypeTemplate !!js/function >\n (str) => {\n let newStr = str.toString();\n if (\n (newStr.charAt(0) === '\"' && newStr.charAt(newStr.length - 1) === '\"') ||\n (newStr.charAt(0) === '\\'' && newStr.charAt(newStr.length - 1) === '\\'')\n ) {\n newStr = newStr.substr(1, newStr.length - 2);\n }\n return newStr;\n }\n RegexTypeTemplate: &RegexTypeTemplate !!js/function >\n (pattern, flags) => {\n return new RegExp(pattern, flags);\n }\n BoolTypeTemplate: &BoolTypeTemplate !!js/function >\n (str) => {\n return str.toLowerCase() === 'true';\n }\n IntegerTypeTemplate: &IntegerTypeTemplate !!js/function >\n (arg) => {\n return parseInt(arg, 10);\n }\n DecimalTypeTemplate: &DecimalTypeTemplate !!js/function >\n (arg) => {\n return parseFloat(arg);\n }\n LongBasicTypeTemplate: &LongBasicTypeTemplate !!js/function >\n (arg) => {\n return parseInt(arg, 10);\n }\n HexTypeTemplate: &HexTypeTemplate !!js/function >\n (arg) => {\n return parseInt(arg, 16);\n }\n OctalTypeTemplate: &OctalTypeTemplate !!js/function >\n (arg) => {\n arg = arg.replace(/[oO]/g, '')\n return parseInt(arg, 8);\n }\n NumericTypeTemplate: &NumericTypeTemplate !!js/function >\n (arg) => {\n if (arg.contains('x')) {\n return parseInt(arg, 16);\n }\n if (arg.contains('o') || arg.startsWith('0')) {\n arg = arg.replace(/o/g, '')\n return parseInt(arg, 8);\n }\n return parseFloat(arg);\n }\n ArrayTypeTemplate: &ArrayTypeTemplate null\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null # Args: single array element, nestedness, lastElement? (note: not being used atm)\n NullTypeTemplate: &NullTypeTemplate !!js/function >\n () => {\n return null;\n }\n UndefinedTypeTemplate: &UndefinedTypeTemplate !!js/function >\n () => {\n return undefined;\n }\n ObjectTypeTemplate: &ObjectTypeTemplate null # Args: literal (for empty array, is empty string. Otherwise all set)\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate null # Args: single object element [2] (i.e. array with [key, value]), nestedness#\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don't take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: &CodeSymbolTemplate null # No args\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate null # Args: code, scope\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate null # No args\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate null # Args: lhs, string (can be empty or null for no arg)\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate null\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate null\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate null\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate null\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate null\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate null\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template null\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate null\n DBRefSymbolTemplate: &DBRefSymbolTemplate null # No args\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null # Args: lhs, coll, id, db\n DoubleSymbolTemplate: &DoubleSymbolTemplate null # No args\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate null # Args: lhs, arg, argType (i.e. '_string', '_double')\n Int32SymbolTemplate: &Int32SymbolTemplate null # No args\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate null # Args: lhs, arg, argType\n LongSymbolTemplate: &LongSymbolTemplate null # No args\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate !!js/function > # Args: lhs, arg, argType\n (lhs, arg) => {\n return lhs.fromNumber(arg);\n }\n RegExpSymbolTemplate: &RegExpSymbolTemplate null # No args\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: &SymbolSymbolTemplate null # No args\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate null # Args: lhs, arg\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate null # No args\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate null # No args\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate null # Args: lhs, arg\n MinKeySymbolTemplate: &MinKeySymbolTemplate null # No args\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate null # No args\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate null # No args\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate null # No args\n TimestampSymbolTemplate: &TimestampSymbolTemplate null # No args\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate null # Args: lhs, low, high\n # non bson-specific\n NumberSymbolTemplate: &NumberSymbolTemplate !!js/function >\n () => {\n return Number;\n }\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate null # Args: lhs, arg, argType\n DateSymbolTemplate: &DateSymbolTemplate null # No args\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate !!js/function >\n (lhs, date, isString) => {\n if (isString) {\n return date.toString();\n }\n return date;\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These're variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: &CodeCodeTemplate null\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate null\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.toString();\n }\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.equals(rhs);\n }\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.getTimestamp();\n }\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.isValid;\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate null\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: &BinarySubtypeTemplate null\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate null\n DBRefGetDBTemplate: &DBRefGetDBTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.db;\n }\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.collection;\n }\n DBRefGetIdTemplate: &DBRefGetIdTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.oid;\n }\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate !!js/function >\n (lhs, rhs) => {\n return lhs;\n }\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate !!js/function >\n (lhs, rhs) => {\n return lhs;\n }\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate !!js/function >\n (lhs, rhs) => {\n return lhs;\n }\n LongEqualsTemplate: &LongEqualsTemplate null\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate null\n LongToStringTemplate: &LongToStringTemplate null\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToIntTemplate: &LongToIntTemplate null\n LongToIntArgsTemplate: &LongToIntArgsTemplate null\n LongValueOfTemplate: &LongValueOfTemplate null\n LongValueOfArgsTemplate: &LongValueOfArgsTemplate null\n LongToNumberTemplate: &LongToNumberTemplate null\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate null\n LongAddTemplate: &LongAddTemplate null\n LongAddArgsTemplate: &LongAddArgsTemplate null\n LongSubtractTemplate: &LongSubtractTemplate null\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate null\n LongMultiplyTemplate: &LongMultiplyTemplate null\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate null\n LongDivTemplate: &LongDivTemplate null\n LongDivArgsTemplate: &LongDivArgsTemplate null\n LongModuloTemplate: &LongModuloTemplate null\n LongModuloArgsTemplate: &LongModuloArgsTemplate null\n LongAndTemplate: &LongAndTemplate null\n LongAndArgsTemplate: &LongAndArgsTemplate null\n LongOrTemplate: &LongOrTemplate null\n LongOrArgsTemplate: &LongOrArgsTemplate null\n LongXorTemplate: &LongXorTemplate null\n LongXorArgsTemplate: &LongXorArgsTemplate null\n LongShiftLeftTemplate: &LongShiftLeftTemplate null\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate null\n LongShiftRightTemplate: &LongShiftRightTemplate null\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate null\n LongCompareTemplate: &LongCompareTemplate null\n LongCompareArgsTemplate: &LongCompareArgsTemplate null\n LongIsOddTemplate: &LongIsOddTemplate null\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate null\n LongIsZeroTemplate: &LongIsZeroTemplate null\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate null\n LongIsNegativeTemplate: &LongIsNegativeTemplate null\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate null\n LongNegateTemplate: &LongNegateTemplate null\n LongNegateArgsTemplate: &LongNegateArgsTemplate null\n LongNotTemplate: &LongNotTemplate null\n LongNotArgsTemplate: &LongNotArgsTemplate null\n LongNotEqualsTemplate: &LongNotEqualsTemplate null\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate null\n LongGreaterThanTemplate: &LongGreaterThanTemplate null\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate null\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate null\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate null\n LongLessThanTemplate: &LongLessThanTemplate null\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate null\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate null\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate null\n LongFloatApproxTemplate: &LongFloatApproxTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.toNumber();\n }\n LongTopTemplate: &LongTopTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.high;\n }\n LongBottomTemplate: &LongBottomTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.low;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate null\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n TimestampEqualsTemplate: &TimestampEqualsTemplate null\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate null\n TimestampGetLowBitsTemplate: &TimestampGetLowBitsTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.getLowBits();\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate !!js/function >\n (lhs, rhs) => {\n return lhs;\n }\n TimestampGetHighBitsTemplate: &TimestampGetHighBitsTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.getHighBits();\n }\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate !!js/function >\n (lhs, rhs) => {\n return lhs;\n }\n TimestampTTemplate: &TimestampTTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.getLowBits();\n }\n TimestampITemplate: &TimestampITemplate !!js/function >\n (lhs, rhs) => {\n return lhs.getHighBits();\n }\n TimestampAsDateTemplate: &TimestampAsDateTemplate !!js/function >\n (lhs, rhs) => {\n return new Date(lhs.getHighBits() * 1000);\n }\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate !!js/function >\n (lhs, rhs) => {\n return lhs;\n }\n TimestampCompareTemplate: &TimestampCompareTemplate null\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate null\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate null\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate null\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate null\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate null\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate null\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate null\n TimestampLessThanTemplate: &TimestampLessThanTemplate null\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate null\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate null\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate null\n SymbolValueOfTemplate: &SymbolValueOfTemplate null\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate null\n SymbolInspectTemplate: &SymbolInspectTemplate null\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate null\n SymbolToStringTemplate: &SymbolToStringTemplate null\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate null\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate null\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # non bson-specific\n DateSymbolNowTemplate: &DateSymbolNowTemplate !!js/function >\n () => {\n return Date.now;\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate null\n\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These're variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don't overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate null\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate null\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate null\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate null\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate null\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate null\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate null\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate null\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate null\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate null\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate null\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate null\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate null\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate null\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate null\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate !!js/function >\n (lhs, rhs) => {\n return lhs.createFromTime;\n }\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate null\n # non bson-specific would go here, but there aren't any atm.\n\n #############################################\n # Imports #\n # #\n # Each type has a 'code' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: &ImportTemplate null\n DriverImportTemplate: &DriverImportTemplate null\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate null\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: &100ImportTemplate null\n 101ImportTemplate: &101ImportTemplate null\n 102ImportTemplate: &102ImportTemplate null\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n 107ImportTemplate: &107ImportTemplate null\n 108ImportTemplate: &108ImportTemplate null\n 109ImportTemplate: &109ImportTemplate null\n 110ImportTemplate: &110ImportTemplate null\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: &112ImportTemplate null\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate null\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; +module.exports = + 'SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace \'null\' with \'!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: \'i\'\n m: \'m\'\n u: \'u\'\n y: \'y\'\n g: \'g\'\n BSONRegexFlags: &BSONRegexFlags\n i: \'i\'\n m: \'m\'\n x: \'x\'\n s: \'s\'\n l: \'l\'\n u: \'u\'\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: &DriverTemplate null\n EqualitySyntaxTemplate: !!js/function &EqualitySyntaxTemplate >\n (lhs, op, rhs) => {\n if (op.includes(\'!\') || op.includes(\'not\')) {\n return lhs !== rhs;\n }\n if (op === \'==\' || op === \'===\' || op === \'is\') {\n if (typeof(lhs) === \'object\' && \'equals\' in lhs) {\n // Use \'.equals\' for objects, if it exists.\n return lhs.equals(rhs);\n }\n return lhs === rhs;\n }\n if (op === \'>\') {\n return lhs > rhs;\n }\n if (op === \'<\') {\n return lhs < rhs;\n }\n if (op === \'>=\') {\n return lhs >= rhs;\n }\n if (op === \'<=\') {\n return lhs <= rhs;\n }\n throw new Error(`unrecognized operation: ${op}`);\n }\n InSyntaxTemplate: !!js/function &InSyntaxTemplate >\n (lhs, op, rhs) => {\n if (op.includes(\'!\') || op.includes(\'not\')) {\n if (typeof rhs === \'array\') {\n return rhs.indexOf(lhs) === -1;\n }\n return !(lhs in rhs);\n }\n if (typeof rhs === \'array\') {\n return rhs.indexOf(lhs) !== -1;\n }\n return lhs in rhs;\n }\n\n AndSyntaxTemplate: !!js/function &AndSyntaxTemplate >\n (args) => {\n return args.reduce((t, k, i) => {\n return t && k;\n });\n }\n OrSyntaxTemplate: !!js/function &OrSyntaxTemplate >\n (args) => {\n return args.reduce((t, k, i) => {\n return t || k;\n });\n }\n NotSyntaxTemplate: !!js/function &NotSyntaxTemplate >\n (arg) => {\n return !arg;\n }\n UnarySyntaxTemplate: !!js/function &UnarySyntaxTemplate >\n (op, arg) => {\n switch(op) {\n case \'+\':\n return +arg;\n case \'-\':\n return -arg;\n case \'~\':\n return ~arg;\n default:\n throw new Error(`unrecognized operation: ${op}`);\n }\n }\n BinarySyntaxTemplate: !!js/function &BinarySyntaxTemplate >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case \'+\':\n return s + rhs;\n case \'-\':\n return s - rhs;\n case \'*\':\n return s * rhs;\n case \'/\':\n return s / rhs;\n case \'**\':\n return Math.pow(s, rhs);\n case \'//\':\n return Math.floor(s, rhs);\n case \'%\':\n return s % rhs;\n case \'>>\':\n return s >> rhs;\n case \'<<\':\n return s << rhs;\n case \'|\':\n return s | rhs;\n case \'&\':\n return s & rhs;\n case \'^\':\n return s ^ rhs;\n default:\n throw new Error(`unrecognized operation: ${op}`);\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: !!js/function &ParensSyntaxTemplate >\n (arg) => {\n return arg;\n }\n EosSyntaxTemplate: !!js/function &EosSyntaxTemplate >\n () => {\n return \'a unique thing\';\n }\n EofSyntaxTemplate: !!js/function &EofSyntaxTemplate >\n () => {\n return \'a unique thing\';\n }\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: !!js/function &StringTypeTemplate >\n (str) => {\n let newStr = str.toString();\n if (\n (newStr.charAt(0) === \'"\' && newStr.charAt(newStr.length - 1) === \'"\') ||\n (newStr.charAt(0) === \'\\\'\' && newStr.charAt(newStr.length - 1) === \'\\\'\')\n ) {\n newStr = newStr.substr(1, newStr.length - 2);\n }\n return newStr;\n }\n RegexTypeTemplate: !!js/function &RegexTypeTemplate >\n (pattern, flags) => {\n return new RegExp(pattern, flags);\n }\n BoolTypeTemplate: !!js/function &BoolTypeTemplate >\n (str) => {\n return str.toLowerCase() === \'true\';\n }\n IntegerTypeTemplate: !!js/function &IntegerTypeTemplate >\n (arg) => {\n return parseInt(arg, 10);\n }\n DecimalTypeTemplate: !!js/function &DecimalTypeTemplate >\n (arg) => {\n return parseFloat(arg);\n }\n LongBasicTypeTemplate: !!js/function &LongBasicTypeTemplate >\n (arg) => {\n return parseInt(arg, 10);\n }\n HexTypeTemplate: !!js/function &HexTypeTemplate >\n (arg) => {\n return parseInt(arg, 16);\n }\n OctalTypeTemplate: !!js/function &OctalTypeTemplate >\n (arg) => {\n arg = arg.replace(/[oO]/g, \'\')\n return parseInt(arg, 8);\n }\n NumericTypeTemplate: !!js/function &NumericTypeTemplate >\n (arg) => {\n if (arg.contains(\'x\')) {\n return parseInt(arg, 16);\n }\n if (arg.contains(\'o\') || arg.startsWith(\'0\')) {\n arg = arg.replace(/o/g, \'\')\n return parseInt(arg, 8);\n }\n return parseFloat(arg);\n }\n ArrayTypeTemplate: &ArrayTypeTemplate null\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null # Args: single array element, nestedness, lastElement? (note: not being used atm)\n NullTypeTemplate: !!js/function &NullTypeTemplate >\n () => {\n return null;\n }\n UndefinedTypeTemplate: !!js/function &UndefinedTypeTemplate >\n () => {\n return undefined;\n }\n ObjectTypeTemplate: &ObjectTypeTemplate null # Args: literal (for empty array, is empty string. Otherwise all set)\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate null # Args: single object element [2] (i.e. array with [key, value]), nestedness#\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don\'t take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: &CodeSymbolTemplate null # No args\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate null # Args: code, scope\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate null # No args\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate null # Args: lhs, string (can be empty or null for no arg)\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate null\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate null\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate null\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate null\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate null\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate null\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template null\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate null\n DBRefSymbolTemplate: &DBRefSymbolTemplate null # No args\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null # Args: lhs, coll, id, db\n DoubleSymbolTemplate: &DoubleSymbolTemplate null # No args\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate null # Args: lhs, arg, argType (i.e. \'_string\', \'_double\')\n Int32SymbolTemplate: &Int32SymbolTemplate null # No args\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate null # Args: lhs, arg, argType\n LongSymbolTemplate: &LongSymbolTemplate null # No args\n LongSymbolArgsTemplate:\n !!js/function &LongSymbolArgsTemplate > # Args: lhs, arg, argType\n (lhs, arg) => {\n return lhs.fromNumber(arg);\n }\n RegExpSymbolTemplate: &RegExpSymbolTemplate null # No args\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: &SymbolSymbolTemplate null # No args\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate null # Args: lhs, arg\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate null # No args\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate null # No args\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate null # Args: lhs, arg\n MinKeySymbolTemplate: &MinKeySymbolTemplate null # No args\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate null # No args\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate null # No args\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate null # No args\n TimestampSymbolTemplate: &TimestampSymbolTemplate null # No args\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate null # Args: lhs, low, high\n # non bson-specific\n NumberSymbolTemplate: !!js/function &NumberSymbolTemplate >\n () => {\n return Number;\n }\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate null # Args: lhs, arg, argType\n DateSymbolTemplate: &DateSymbolTemplate null # No args\n DateSymbolArgsTemplate: !!js/function &DateSymbolArgsTemplate >\n (lhs, date, isString) => {\n if (isString) {\n return date.toString();\n }\n return date;\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These\'re variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: &CodeCodeTemplate null\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate null\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: !!js/function &ObjectIdToStringTemplate >\n (lhs, rhs) => {\n return lhs.toString();\n }\n ObjectIdToStringArgsTemplate: !!js/function &ObjectIdToStringArgsTemplate >\n (lhs) => {\n return lhs;\n }\n ObjectIdEqualsTemplate: !!js/function &ObjectIdEqualsTemplate >\n (lhs) => {\n return lhs;\n }\n ObjectIdEqualsArgsTemplate: !!js/function &ObjectIdEqualsArgsTemplate >\n (lhs, rhs) => {\n return lhs.equals(rhs);\n }\n ObjectIdGetTimestampTemplate: !!js/function &ObjectIdGetTimestampTemplate >\n (lhs, rhs) => {\n return lhs.getTimestamp();\n }\n ObjectIdGetTimestampArgsTemplate:\n !!js/function &ObjectIdGetTimestampArgsTemplate >\n (lhs) => {\n return lhs;\n }\n ObjectIdIsValidTemplate: !!js/function &ObjectIdIsValidTemplate >\n (lhs, rhs) => {\n return lhs.isValid;\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate null\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: &BinarySubtypeTemplate null\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate null\n DBRefGetDBTemplate: !!js/function &DBRefGetDBTemplate >\n (lhs, rhs) => {\n return lhs.db;\n }\n DBRefGetCollectionTemplate: !!js/function &DBRefGetCollectionTemplate >\n (lhs, rhs) => {\n return lhs.collection;\n }\n DBRefGetIdTemplate: !!js/function &DBRefGetIdTemplate >\n (lhs, rhs) => {\n return lhs.oid;\n }\n DBRefGetDBArgsTemplate: !!js/function &DBRefGetDBArgsTemplate >\n (lhs, rhs) => {\n return lhs;\n }\n DBRefGetCollectionArgsTemplate:\n !!js/function &DBRefGetCollectionArgsTemplate >\n (lhs, rhs) => {\n return lhs;\n }\n DBRefGetIdArgsTemplate: !!js/function &DBRefGetIdArgsTemplate >\n (lhs, rhs) => {\n return lhs;\n }\n LongEqualsTemplate: &LongEqualsTemplate null\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate null\n LongToStringTemplate: &LongToStringTemplate null\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToIntTemplate: &LongToIntTemplate null\n LongToIntArgsTemplate: &LongToIntArgsTemplate null\n LongValueOfTemplate: &LongValueOfTemplate null\n LongValueOfArgsTemplate: &LongValueOfArgsTemplate null\n LongToNumberTemplate: &LongToNumberTemplate null\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate null\n LongAddTemplate: &LongAddTemplate null\n LongAddArgsTemplate: &LongAddArgsTemplate null\n LongSubtractTemplate: &LongSubtractTemplate null\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate null\n LongMultiplyTemplate: &LongMultiplyTemplate null\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate null\n LongDivTemplate: &LongDivTemplate null\n LongDivArgsTemplate: &LongDivArgsTemplate null\n LongModuloTemplate: &LongModuloTemplate null\n LongModuloArgsTemplate: &LongModuloArgsTemplate null\n LongAndTemplate: &LongAndTemplate null\n LongAndArgsTemplate: &LongAndArgsTemplate null\n LongOrTemplate: &LongOrTemplate null\n LongOrArgsTemplate: &LongOrArgsTemplate null\n LongXorTemplate: &LongXorTemplate null\n LongXorArgsTemplate: &LongXorArgsTemplate null\n LongShiftLeftTemplate: &LongShiftLeftTemplate null\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate null\n LongShiftRightTemplate: &LongShiftRightTemplate null\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate null\n LongCompareTemplate: &LongCompareTemplate null\n LongCompareArgsTemplate: &LongCompareArgsTemplate null\n LongIsOddTemplate: &LongIsOddTemplate null\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate null\n LongIsZeroTemplate: &LongIsZeroTemplate null\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate null\n LongIsNegativeTemplate: &LongIsNegativeTemplate null\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate null\n LongNegateTemplate: &LongNegateTemplate null\n LongNegateArgsTemplate: &LongNegateArgsTemplate null\n LongNotTemplate: &LongNotTemplate null\n LongNotArgsTemplate: &LongNotArgsTemplate null\n LongNotEqualsTemplate: &LongNotEqualsTemplate null\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate null\n LongGreaterThanTemplate: &LongGreaterThanTemplate null\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate null\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate null\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate null\n LongLessThanTemplate: &LongLessThanTemplate null\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate null\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate null\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate null\n LongFloatApproxTemplate: !!js/function &LongFloatApproxTemplate >\n (lhs, rhs) => {\n return lhs.toNumber();\n }\n LongTopTemplate: !!js/function &LongTopTemplate >\n (lhs, rhs) => {\n return lhs.high;\n }\n LongBottomTemplate: !!js/function &LongBottomTemplate >\n (lhs, rhs) => {\n return lhs.low;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate null\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate null\n TimestampEqualsTemplate: &TimestampEqualsTemplate null\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate null\n TimestampGetLowBitsTemplate: !!js/function &TimestampGetLowBitsTemplate >\n (lhs, rhs) => {\n return lhs.getLowBits();\n }\n TimestampGetLowBitsArgsTemplate:\n !!js/function &TimestampGetLowBitsArgsTemplate >\n (lhs, rhs) => {\n return lhs;\n }\n TimestampGetHighBitsTemplate: !!js/function &TimestampGetHighBitsTemplate >\n (lhs, rhs) => {\n return lhs.getHighBits();\n }\n TimestampGetHighBitsArgsTemplate:\n !!js/function &TimestampGetHighBitsArgsTemplate >\n (lhs, rhs) => {\n return lhs;\n }\n TimestampTTemplate: !!js/function &TimestampTTemplate >\n (lhs, rhs) => {\n return lhs.getLowBits();\n }\n TimestampITemplate: !!js/function &TimestampITemplate >\n (lhs, rhs) => {\n return lhs.getHighBits();\n }\n TimestampAsDateTemplate: !!js/function &TimestampAsDateTemplate >\n (lhs, rhs) => {\n return new Date(lhs.getHighBits() * 1000);\n }\n TimestampAsDateArgsTemplate: !!js/function &TimestampAsDateArgsTemplate >\n (lhs, rhs) => {\n return lhs;\n }\n TimestampCompareTemplate: &TimestampCompareTemplate null\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate null\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate null\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate null\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate null\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate null\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate null\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate null\n TimestampLessThanTemplate: &TimestampLessThanTemplate null\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate null\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate null\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate null\n SymbolValueOfTemplate: &SymbolValueOfTemplate null\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate null\n SymbolInspectTemplate: &SymbolInspectTemplate null\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate null\n SymbolToStringTemplate: &SymbolToStringTemplate null\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate null\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate null\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # non bson-specific\n DateSymbolNowTemplate: !!js/function &DateSymbolNowTemplate >\n () => {\n return Date.now;\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate null\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These\'re variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don\'t overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate null\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate null\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate null\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate null\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate null\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate null\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate null\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate null\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate null\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate null\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate null\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate null\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate null\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate null\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate null\n ObjectIdCreateFromTimeTemplate:\n !!js/function &ObjectIdCreateFromTimeTemplate >\n (lhs, rhs) => {\n return lhs.createFromTime;\n }\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate null\n # non bson-specific would go here, but there aren\'t any atm.\n\n #############################################\n # Imports #\n # #\n # Each type has a \'code\' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: &ImportTemplate null\n DriverImportTemplate: &DriverImportTemplate null\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate null\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: &100ImportTemplate null\n 101ImportTemplate: &101ImportTemplate null\n 102ImportTemplate: &102ImportTemplate null\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n 107ImportTemplate: &107ImportTemplate null\n 108ImportTemplate: &108ImportTemplate null\n 109ImportTemplate: &109ImportTemplate null\n 110ImportTemplate: &110ImportTemplate null\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: &112ImportTemplate null\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate null\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven\'t implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: "_bool"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: "_integer"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: "_long"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: "_decimal"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: "_hex"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: "_octal"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: "_numeric"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: "_string"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: "_regex"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: "_array"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: "_object"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: "_null"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: "_undefined"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn\'t add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren\'t defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: "Code"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: "code"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: "scope"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: "ObjectId"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: "equals"\n args:\n - [ "ObjectId" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: "getTimestamp"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: "BinData"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: "base64"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: "length"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: "subtype"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: "DBRef"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: "getDb"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: "$db"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: "getCollection"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: "getRef"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: "$ref"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: "getId"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: "$id"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: "NumberInt"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: "NumberLong"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "LongtoString" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: "equals"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: "toInt"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: "toNumber"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: "compare"\n args:\n - [ "Long" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: "isOdd"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: "isZero"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: "isNegative"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: "negate"\n type: "Long"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: "not"\n type: "Long"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: "notEquals"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: "greaterThan"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: "greaterThanOrEqual"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: "lessThan"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: "lessThanOrEqual"\n args:\n - [ "Long" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: "add"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: "subtract"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: "multiply"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: "div"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: "modulo"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: "and"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: "or"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: "xor"\n args:\n - [ "Long" ]\n type: "Long"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: "shiftLeft"\n args:\n - [ *IntegerType ]\n type: "Long"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: "shiftRight"\n args:\n - [ *IntegerType ]\n type: "Long"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: "MinKey"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: "MaxKey"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: "Timestamp"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: "equals"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: "getLowBits"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: "getHighBits"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: "compare"\n args:\n - [ "Timestamp" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: "notEquals"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: "greaterThan"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: "greaterThanOrEqual"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: "lessThan"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: "lessThanOrEqual"\n args:\n - [ "Timestamp" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: "BSONSymbol"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: "valueOf"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: "inspect"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: "Double"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: "Decimal128"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: "NumberDecimal"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: "toString"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: "SUBTYPE_DEFAULT"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: "SUBTYPE_FUNCTION"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: "SUBTYPE_BYTE_ARRAY"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: "SUBTYPE_UUID_OLD"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: "SUBTYPE_UUID"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: "SUBTYPE_MD5"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: "SUBTYPE_USER_DEFINED"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: "BSONRegExp"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: "Date"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: "RegExp"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: "Code"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: "ObjectId"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: "createFromHexString"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: "ObjectIdCreateFromTime"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: "isValid"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: "BinData"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: "DBRef"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: "Int32"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: "NumberLong"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: "MinKey"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: "MaxKey"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: "Timestamp"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: "Symbol"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: "NumberDecimal"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: "BSONRegExp"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: "BSONSymbol"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: "Decimal128"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: "fromString"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: "Double"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: "Int32"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: "Long"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: "MAX_VALUE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: "MIN_VALUE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: "ZERO"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: "ONE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: "NEG_ONE"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: "LongfromBits" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: "fromInt"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: "fromNumber"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: "fromString"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: "Number"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: "Date"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: "now"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: "ISODate"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: "now"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: "RegExp"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n'; diff --git a/packages/bson-transpilers/lib/symbol-table/shelltophp.js b/packages/bson-transpilers/lib/symbol-table/shelltophp.js index 395a5953062..00204466a68 100644 --- a/packages/bson-transpilers/lib/symbol-table/shelltophp.js +++ b/packages/bson-transpilers/lib/symbol-table/shelltophp.js @@ -1 +1,2 @@ -module.exports="SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace 'null' with '!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: ''\n y: ''\n g: ''\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: ''\n u: ''\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: &DriverTemplate !!js/function >\n (spec) => {\n const getKey = k => {\n let translateKey = {\n project: 'projection',\n }\n return k in translateKey ? translateKey[k] : k\n };\n const options = spec.options;\n const filter = spec.filter || {};\n const exportMode = spec.exportMode;\n delete spec.options;\n delete spec.filter;\n delete spec.exportMode;\n\n comment = []\n .concat('// Requires the MongoDB PHP Driver')\n .concat('// https://www.mongodb.com/docs/drivers/php/')\n .join('\\n')\n ;\n const client = `$client = new Client('${options.uri}');`;\n const collection = `$collection = $client->selectCollection('${options.database}', '${options.collection}');`;\n\n if ('aggregation' in spec) {\n // Note: toPHPArray() may not be required here as Compass should always provide an array for spec.aggregation\n return []\n .concat(comment)\n .concat('')\n .concat(client)\n .concat(collection)\n .concat(`$cursor = $collection->aggregate(${this.utils.toPHPArray(spec.aggregation)});`)\n .join('\\n')\n ;\n }\n\n let driverMethod;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'delete_many';\n break;\n case 'Update Query':\n driverMethod = 'update_many';\n break;\n default:\n driverMethod = 'find';\n }\n\n let args = Object.keys(spec).reduce(\n (result, k) => {\n let val = this.utils.removePHPObject(spec[k]);\n const divider = result === '' ? '' : ',\\n';\n return `${result}${divider} '${getKey(k)}' => ${val}`;\n },\n ''\n );\n args = args ? `, [\\n${args}\\n]` : '';\n\n return []\n .concat(comment)\n .concat('')\n .concat(client)\n .concat(collection)\n .concat(`$cursor = $collection->${driverMethod}(${this.utils.removePHPObject(filter)}${args});`)\n .join('\\n')\n ;\n }\n EqualitySyntaxTemplate: &EqualitySyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n // Identity comparison\n if (op.includes('is')) {\n if (op.includes('not')) {\n return `${lhs} !== ${rhs}`;\n } else {\n return `${lhs} === ${rhs}`;\n }\n }\n // Not equal\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n }\n // Equal\n if (op === '==' || op === '===') {\n return `${lhs} == ${rhs}`;\n }\n // All other cases\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: &InSyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n // array\n if (rhs.charAt(0) === '[' && rhs.charAt(rhs.length - 1) === ']') {\n let not = '';\n if (op.includes('!') || op.includes('not')) {\n not = '! ';\n }\n return `${not}\\\\in_array(${lhs}, ${rhs})`;\n }\n \n //object\n if (rhs.indexOf('(object) ') === 0) {\n let not = '';\n if (op.includes('!') || op.includes('not')) {\n not = '! ';\n }\n return `${not}\\\\property_exists(${rhs}, ${lhs})`;\n }\n \n // string - all other cases\n let targop = '!==';\n if (op.includes('!') || op.includes('not')) {\n targop = '===';\n }\n return `\\\\strpos(${rhs}, ${lhs}) ${targop} false`;\n }\n AndSyntaxTemplate: &AndSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: &OrSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: &NotSyntaxTemplate !!js/function >\n (arg) => {\n return `! ${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate !!js/function >\n (op, arg) => {\n switch(op) {\n case '+':\n return `+${arg}`;\n case '-':\n return `-${arg}`;\n case '~':\n return `~${arg}`;\n default:\n throw new Error(`unrecognized operation: ${op}`);\n }\n }\n BinarySyntaxTemplate: &BinarySyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '+':\n return `${s} + ${rhs}`;\n case '-':\n return `${s} - ${rhs}`;\n case '*':\n return `${s} * ${rhs}`;\n case '/':\n return `${s} / ${rhs}`;\n case '**':\n return `${s} ** ${rhs}`;\n case '//':\n return `\\\\intdiv(${s}, ${rhs})`;\n case '%':\n return `${s} % ${rhs}`;\n case '>>':\n return `${s} >> ${rhs}`;\n case '<<':\n return `${s} << ${rhs}`;\n case '|':\n return `${s} | ${rhs}`;\n case '&':\n return `${s} & ${rhs}`;\n case '^':\n return `${s} ^ ${rhs}`;\n default:\n throw new Error(`unrecognized operation: ${op}`);\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosTemplate: &EosSyntaxTemplate null # No args. End-of-line\n EofTemplate: &EofSyntaxTemplate null # No args. End-of-file\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: &StringTypeTemplate !!js/function >\n (str) => {\n // This is some standalone object context, which is generated to parse \n // node and doesn't have access to main Generator object. Thus we can't\n // use utility function call. All ~Template calls use this type of \n // context. All ~ArgsTemplate have access to utility functions.\n \n stringifyWithSingleQuotes = (str) => {\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')\n ) {\n str = str.substr(1, str.length - 2);\n }\n return `'${str.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n };\n\n return `${stringifyWithSingleQuotes(str)}`;\n }\n RegexTypeTemplate: &RegexTypeTemplate !!js/function >\n (pattern, flags) => {\n // This is some standalone object context, which is generated to parse \n // node and doesn't have access to main Generator object. Thus we can't\n // use utility function call. All ~Template calls use this type of \n // context. All ~ArgsTemplate have access to utility functions.\n\n stringifyWithDoubleQuotes = (str) => {\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')\n ) {\n str = str.substr(1, str.length - 2);\n }\n return `${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}`;\n };\n \n pattern = `\"${stringifyWithDoubleQuotes(pattern)}\"`;\n flags = flags ? `, \"${flags}\"` : '';\n\n return `new Regex(${pattern}${flags})`;\n }\n BoolTypeTemplate: &BoolTypeTemplate !!js/function >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null # args: literal, argType (i.e. '_string', '_decimal' etc)\n DecimalTypeTemplate: &DecimalTypeTemplate null # args: literal, argType\n LongBasicTypeTemplate: &LongBasicTypeTemplate null # args: literal, argType\n HexTypeTemplate: &HexTypeTemplate null # args: literal, argType\n OctalTypeTemplate: &OctalTypeTemplate !!js/function >\n (literal) => {\n let offset = 0;\n\n if (\n literal.charAt(0) === '0' &&\n (literal.charAt(1) === '0' || literal.charAt(1) === 'o' || literal.charAt(1) === 'O')\n ) {\n offset = 2;\n } else if (literal.charAt(0) === '0') {\n offset = 1;\n }\n\n literal = `0${literal.substr(offset, literal.length - 1)}`;\n\n return literal;\n }\n NumericTypeTemplate: &NumericTypeTemplate null # args: literal, argType\n ArrayTypeTemplate: &ArrayTypeTemplate !!js/function >\n (literal, depth) => {\n if (literal === '') {\n return '[]'\n }\n return `[${literal}]`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null # Args: single array element, nestedness, lastElement? (note: not being used atm)\n NullTypeTemplate: &NullTypeTemplate !!js/function >\n () => {\n return 'null';\n }\n UndefinedTypeTemplate: &UndefinedTypeTemplate !!js/function >\n () => {\n return 'null';\n }\n ObjectTypeTemplate: &ObjectTypeTemplate !!js/function >\n (literal) => {\n return `${literal}`;\n }\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate !!js/function >\n (args, depth) => {\n let isObjectCastRequired = true;\n \n if (args.length === 0) {\n return `(object) []`;\n }\n\n const isExpectedIndex = (actualIndex, expectedIndex) => {\n return '' + actualIndex === '' + expectedIndex;\n }\n \n let indexTest = 0;\n let pairs = args.map((arg) => {\n if (isObjectCastRequired && !isExpectedIndex(arg[0], indexTest)) {\n isObjectCastRequired = false;\n }\n indexTest++;\n return `${this.utils.stringifyWithSingleQuotes(arg[0])} => ${arg[1]}`;\n }).join(', ');\n\n // Rebuilding pairs for numeric sequential indexes without quotes\n if (isObjectCastRequired) {\n pairs = args.map((arg) => {\n return `${arg[0]} => ${arg[1]}`;\n }).join(', ');\n }\n\n return `${isObjectCastRequired ? '(object) ' : ''}[${pairs}]`;\n }\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don't take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: &CodeSymbolTemplate !!js/function >\n () => {\n return 'new Javascript';\n }\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate !!js/function >\n (lhs, code, scope) => {\n return !scope \n ? `(${this.utils.stringifyWithSingleQuotes(code)})` \n : `(${this.utils.stringifyWithSingleQuotes(code)}, ${scope})`\n ;\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate !!js/function >\n () => {\n return 'new ObjectId';\n }\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate !!js/function >\n (lhs, id) => {\n return !id \n ? `()` \n : `(${this.utils.stringifyWithSingleQuotes(id)})`\n ;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate !!js/function >\n () => {\n return 'new Binary';\n }\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate !!js/function >\n (lhs, bytes, type) => {\n if (type === null) {\n type = 'Binary::TYPE_GENERIC';\n }\n return `(${this.utils.stringifyWithSingleQuotes(bytes)}, ${type})`;\n }\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate !!js/function >\n () => {\n return 'Binary::TYPE_GENERIC';\n }\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate !!js/function >\n () => {\n return 'Binary::TYPE_FUNCTION';\n }\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate !!js/function >\n () => {\n return 'Binary::TYPE_OLD_BINARY';\n }\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate !!js/function >\n () => {\n return 'Binary::TYPE_OLD_UUID';\n }\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate !!js/function >\n () => {\n return 'Binary::TYPE_UUID';\n }\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template !!js/function >\n () => {\n return 'Binary::TYPE_MD5';\n }\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate !!js/function >\n () => {\n return 'Binary::TYPE_USER_DEFINED';\n }\n DBRefSymbolTemplate: &DBRefSymbolTemplate !!js/function >\n () => {\n return ''\n }\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate !!js/function >\n (lhs, coll, id, db) => {\n let coll_string = `'$ref' => ${this.utils.stringifyWithSingleQuotes(coll)}`;\n let id_string = `, '$id' => ${id}`;\n let db_string = db ? `, '$db' => ${this.utils.stringifyWithSingleQuotes(db)}` : `, '$db' => null`;\n return `[${coll_string}${id_string}${db_string}]`;\n }\n DoubleSymbolTemplate: &DoubleSymbolTemplate !!js/function >\n () => {\n return '';\n }\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_decimal' || type === '_double') {\n return arg;\n }\n if (type === '_integer' || type === '_long') {\n return `${arg}.0`;\n }\n return `(float) ${arg}`;\n }\n Int32SymbolTemplate: &Int32SymbolTemplate !!js/function >\n () => {\n return '';\n }\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long' || type === '_hex' || type === '_octal') {\n return arg;\n }\n return `(int) ${arg}`;\n }\n LongSymbolTemplate: &LongSymbolTemplate !!js/function >\n () => {\n return ''\n }\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long' || type === '_hex' || type === '_octal') {\n return arg;\n }\n return `(int) ${arg}`;\n }\n RegExpSymbolTemplate: &RegExpSymbolTemplate !!js/function >\n () => {\n return 'new Regex';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: &SymbolSymbolTemplate !!js/function >\n () => {\n return '';\n }\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n return arg;\n }\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate !!js/function >\n () => {\n return 'new Regex';\n }\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate !!js/function >\n (lhs, pattern, flags) => {\n return `(${this.utils.stringifyWithDoubleQuotes(pattern)}${flags ? ', ' + this.utils.stringifyWithDoubleQuotes(flags) : ''})`;\n }\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate !!js/function >\n () => {\n return 'new Decimal128';\n }\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n arg = arg === undefined ? '0' : arg.toString();\n return `('${this.utils.removeStringQuotes(arg)}')`;\n }\n MinKeySymbolTemplate: &MinKeySymbolTemplate !!js/function >\n () => {\n return 'new MinKey';\n }\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate !!js/function >\n () => {\n return `()`;\n }\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate !!js/function >\n () => {\n return 'new MaxKey';\n }\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate !!js/function >\n () => {\n return `()`;\n }\n TimestampSymbolTemplate: &TimestampSymbolTemplate !!js/function >\n () => {\n return 'new Timestamp';\n }\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate !!js/function >\n (lhs, arg1, arg2) => {\n // PHP orders increment and timestamp args differently (see: PHPC-845)\n return `(${arg2 === undefined ? 0 : arg2}, ${arg1 === undefined ? 0 : arg1})`;\n }\n # non bson-specific\n NumberSymbolTemplate: &NumberSymbolTemplate !!js/function >\n () => ''\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n switch(type) {\n case '_string':\n if ((arg.indexOf('.') !== -1) && (arg.indexOf('.') !== arg.length - 2)) {\n return `(float) ${arg}`\n }\n return `(int) ${arg}`\n default:\n return `${arg}`\n }\n }\n DateSymbolTemplate: &DateSymbolTemplate !!js/function >\n () => {\n return 'UTCDateTime';\n }\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate !!js/function >\n (lhs, date, isString) => {\n if (date === null) {\n return `new ${lhs}()`;\n }\n return isString \n ? `(new ${lhs}(${date.getTime()}))->toDateTime()->format(\\\\DateTimeInterface::RFC3339_EXTENDED)`\n : `new ${lhs}(${date.getTime()})`\n ;\n }\n DateSymbolNowTemplate: &DateSymbolNowTemplate !!js/function >\n () => {\n return `new UTCDateTime()`;\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate !!js/function >\n (args) => {\n return '';\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These're variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: &CodeCodeTemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getCode()`;\n }\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate !!js/function >\n () => {\n return '';\n }\n CodeScopeTemplate: &CodeScopeTemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getScope()`;\n }\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate !!js/function >\n () => {\n return '';\n }\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate !!js/function >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} == `;\n }\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate !!js/function >\n (arg) => {\n return `${arg}`;\n }\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getTimestamp()`;\n }\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate !!js/function >\n () => {\n return '';\n }\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate !!js/function >\n (lhs) => {\n return ``;\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(\\\\ctype_xdigit(${this.utils.stringifyWithSingleQuotes(arg)}) && \\\\strlen(${this.utils.stringifyWithSingleQuotes(arg)}) == 24)`;\n }\n BinaryValueTemplate: &BinaryValueTemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getData()`;\n }\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate !!js/function >\n () => {\n return '';\n }\n BinaryLengthTemplate: &BinaryLengthTemplate !!js/function >\n (lhs) => {\n return `\\\\strlen((${lhs})->getData())`;\n }\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate !!js/function >\n () => {\n return '';\n }\n BinaryToStringTemplate: &BinaryToStringTemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getData()`;\n }\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n BinarySubtypeTemplate: &BinarySubtypeTemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getType()`;\n }\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetDBTemplate: &DBRefGetDBTemplate !!js/function >\n (lhs) => {\n return `${lhs}['$db']`;\n }\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate !!js/function >\n (lhs) => {\n return `${lhs}['$ref']`;\n }\n DBRefGetIdTemplate: &DBRefGetIdTemplate !!js/function >\n (lhs) => {\n return `${lhs}['$id']`;\n }\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n DBRefToStringTemplate: &DBRefToStringTemplate null\n DBRefToStringArgsTemplate: &DBRefToStringArgsTemplate null\n DoubleValueOfTemplate: &DoubleValueOfTemplate null\n DoubleValueOfArgsTemplate: &DoubleValueOfArgsTemplate null\n Int32ValueOfTemplate: &Int32ValueOfTemplate null\n Int32ValueOfArgsTemplate: &Int32ValueOfArgsTemplate null\n Int32ToStringTemplate: &Int32ToStringTemplate !!js/function >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n Int32ToStringArgsTemplate: &Int32ToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongEqualsTemplate: &LongEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} ==`;\n }\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongToStringTemplate: &LongToStringTemplate !!js/function >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n LongToStringArgsTemplate: &LongToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongToIntTemplate: &LongToIntTemplate !!js/function >\n (lhs) => {\n return `${lhs}`;\n }\n LongToIntArgsTemplate: &LongToIntArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongValueOfTemplate: &LongValueOfTemplate null\n LongValueOfArgsTemplate: &LongValueOfArgsTemplate null\n LongToNumberTemplate: &LongToNumberTemplate !!js/function >\n (lhs) => {\n return `(float) ${lhs}`;\n }\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongAddTemplate: &LongAddTemplate !!js/function >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: &LongAddArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: &LongSubtractTemplate !!js/function >\n (arg) => {\n return `${arg} -`;\n }\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: &LongMultiplyTemplate !!js/function >\n (arg) => {\n return `${arg} *`;\n }\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: &LongDivTemplate !!js/function >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: &LongDivArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: &LongModuloTemplate !!js/function >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: &LongModuloArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: &LongAndTemplate !!js/function >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: &LongAndArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: &LongOrTemplate !!js/function >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: &LongOrArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: &LongXorTemplate !!js/function >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: &LongXorArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: &LongShiftLeftTemplate !!js/function >\n (lhs) => {\n return `${lhs} <<`;\n }\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftRightTemplate: &LongShiftRightTemplate !!js/function >\n (lhs) => {\n return `${lhs} >>`;\n }\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongCompareTemplate: &LongCompareTemplate !!js/function >\n (lhs) => {\n return `${lhs} <=>`;\n }\n LongCompareArgsTemplate: &LongCompareArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongIsOddTemplate: &LongIsOddTemplate !!js/function >\n (lhs) => {\n return `(${lhs} % 2) === 1`;\n }\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongIsZeroTemplate: &LongIsZeroTemplate !!js/function >\n (lhs) => {\n return `${lhs} === 0`;\n }\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongIsNegativeTemplate: &LongIsNegativeTemplate !!js/function >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongNegateTemplate: &LongNegateTemplate !!js/function >\n () => {\n return '-';\n }\n LongNegateArgsTemplate: &LongNegateArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongNotTemplate: &LongNotTemplate !!js/function >\n () => {\n return '~';\n }\n LongNotArgsTemplate: &LongNotArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongNotEqualsTemplate: &LongNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: &LongGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: &LongLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: &LongFloatApproxTemplate !!js/function >\n (lhs) => {\n return `(float) ${lhs}`;\n }\n LongTopTemplate: &LongTopTemplate !!js/function >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: &LongBottomTemplate !!js/function >\n (lhs) => {\n return `${lhs} & 0x00000000ffffffff`;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate !!js/function >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n TimestampEqualsTemplate: &TimestampEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} == `;\n }\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGetLowBitsTemplate: &TimestampGetLowBitsTemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getTimestamp()`;\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate !!js/function >\n () => {\n return ''\n }\n TimestampGetHighBitsTemplate: &TimestampGetHighBitsTemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getIncrement()`;\n }\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate !!js/function >\n () => {\n return ''\n }\n TimestampTTemplate: &TimestampTTemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getTimestamp()`;\n }\n TimestampITemplate: &TimestampITemplate !!js/function >\n (lhs) => {\n return `(${lhs})->getIncrement()`;\n }\n TimestampAsDateTemplate: &TimestampAsDateTemplate !!js/function >\n (lhs) => {\n return `new UTCDateTime((${lhs})->getTimestamp() * 1000)`;\n }\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate null\n TimestampCompareTemplate: &TimestampCompareTemplate !!js/function >\n (lhs) => {\n return `${lhs} <=> `;\n }\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} != `;\n }\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} > `;\n }\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} >= `;\n }\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanTemplate: &TimestampLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} < `;\n }\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} <= `;\n }\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n SymbolValueOfTemplate: &SymbolValueOfTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate !!js/function >\n () => {\n return '';\n }\n SymbolInspectTemplate: &SymbolInspectTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate !!js/function >\n () => {\n return '';\n }\n SymbolToStringTemplate: &SymbolToStringTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate !!js/function >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These're variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don't overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate !!js/function >\n () => {\n return '\\\\PHP_INT_MAX';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate !!js/function >\n () => {\n return '\\\\PHP_INT_MIN';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate !!js/function >\n () => {\n return '0';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate !!js/function >\n () => {\n return '1';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate !!js/function >\n () => {\n return '-1';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(int) ${arg}`;\n }\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate !!js/function >\n (lhs, arg) => {\n return arg;\n }\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(int) ${arg}`;\n }\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(int) ${arg}`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate !!js/function >\n () => {\n return 'new Decimal128';\n }\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate !!js/function >\n () => {\n return 'new ObjectId';\n }\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate !!js/function >\n () => {\n return 'new ObjectId';\n }\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate !!js/function >\n (lhs, arg, isNumber) => {\n if (!isNumber) {\n return `(\\\\str_pad(\\\\bin2hex(\\\\pack('N', (${arg})->toDateTime()->getTimestamp())), 24, '0'))`;\n }\n return `(\\\\str_pad(\\\\bin2hex(\\\\pack('N', ${arg})), 24, '0'))`;\n }\n # non bson-specific would go here, but there aren't any atm.\n\n #############################################\n # Imports #\n # #\n # Each type has a 'code' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: &ImportTemplate !!js/function >\n (args) => {\n let set = new Set(Object.values(args));\n return [...set].sort().join('\\n');\n }\n DriverImportTemplate: &DriverImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\Client;`;\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n # Common internal Regexp\n 8ImportTemplate: &8ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\Regex;`;\n }\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n # Code\n 100ImportTemplate: &100ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\Javascript;`;\n }\n # ObjectId\n 101ImportTemplate: &101ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\ObjectId;`;\n }\n # Binary\n 102ImportTemplate: &102ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\Binary;`;\n }\n # DBRef\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n # Int64\n 106ImportTemplate: &106ImportTemplate null\n # MinKey\n 107ImportTemplate: &107ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\MinKey;`;\n }\n # MaxKey\n 108ImportTemplate: &108ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\MaxKey;`;\n }\n # Regex\n 109ImportTemplate: &109ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\Regex;`;\n }\n # Timestamp\n 110ImportTemplate: &110ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\Timestamp;`;\n }\n 111ImportTemplate: &111ImportTemplate null\n # Decimal128\n 112ImportTemplate: &112ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\Decimal128;`;\n }\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate !!js/function >\n () => {\n return `use MongoDB\\\\BSON\\\\UTCDateTime;`;\n }\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; +module.exports = + "SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace 'null' with '!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: ''\n y: ''\n g: ''\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: ''\n u: ''\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: !!js/function &DriverTemplate >\n (spec) => {\n const getKey = k => {\n let translateKey = {\n project: 'projection',\n }\n return k in translateKey ? translateKey[k] : k\n };\n const options = spec.options;\n const filter = spec.filter || {};\n const exportMode = spec.exportMode;\n delete spec.options;\n delete spec.filter;\n delete spec.exportMode;\n\n comment = []\n .concat('// Requires the MongoDB PHP Driver')\n .concat('// https://www.mongodb.com/docs/drivers/php/')\n .join('\\n')\n ;\n const client = `$client = new Client('${options.uri}');`;\n const collection = `$collection = $client->selectCollection('${options.database}', '${options.collection}');`;\n\n if ('aggregation' in spec) {\n // Note: toPHPArray() may not be required here as Compass should always provide an array for spec.aggregation\n return []\n .concat(comment)\n .concat('')\n .concat(client)\n .concat(collection)\n .concat(`$cursor = $collection->aggregate(${this.utils.toPHPArray(spec.aggregation)});`)\n .join('\\n')\n ;\n }\n\n let driverMethod;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'delete_many';\n break;\n case 'Update Query':\n driverMethod = 'update_many';\n break;\n default:\n driverMethod = 'find';\n }\n\n let args = Object.keys(spec).reduce(\n (result, k) => {\n let val = this.utils.removePHPObject(spec[k]);\n const divider = result === '' ? '' : ',\\n';\n return `${result}${divider} '${getKey(k)}' => ${val}`;\n },\n ''\n );\n args = args ? `, [\\n${args}\\n]` : '';\n\n return []\n .concat(comment)\n .concat('')\n .concat(client)\n .concat(collection)\n .concat(`$cursor = $collection->${driverMethod}(${this.utils.removePHPObject(filter)}${args});`)\n .join('\\n')\n ;\n }\n EqualitySyntaxTemplate: !!js/function &EqualitySyntaxTemplate >\n (lhs, op, rhs) => {\n // Identity comparison\n if (op.includes('is')) {\n if (op.includes('not')) {\n return `${lhs} !== ${rhs}`;\n } else {\n return `${lhs} === ${rhs}`;\n }\n }\n // Not equal\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n }\n // Equal\n if (op === '==' || op === '===') {\n return `${lhs} == ${rhs}`;\n }\n // All other cases\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: !!js/function &InSyntaxTemplate >\n (lhs, op, rhs) => {\n // array\n if (rhs.charAt(0) === '[' && rhs.charAt(rhs.length - 1) === ']') {\n let not = '';\n if (op.includes('!') || op.includes('not')) {\n not = '! ';\n }\n return `${not}\\\\in_array(${lhs}, ${rhs})`;\n }\n \n //object\n if (rhs.indexOf('(object) ') === 0) {\n let not = '';\n if (op.includes('!') || op.includes('not')) {\n not = '! ';\n }\n return `${not}\\\\property_exists(${rhs}, ${lhs})`;\n }\n \n // string - all other cases\n let targop = '!==';\n if (op.includes('!') || op.includes('not')) {\n targop = '===';\n }\n return `\\\\strpos(${rhs}, ${lhs}) ${targop} false`;\n }\n AndSyntaxTemplate: !!js/function &AndSyntaxTemplate >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: !!js/function &OrSyntaxTemplate >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: !!js/function &NotSyntaxTemplate >\n (arg) => {\n return `! ${arg}`;\n }\n UnarySyntaxTemplate: !!js/function &UnarySyntaxTemplate >\n (op, arg) => {\n switch(op) {\n case '+':\n return `+${arg}`;\n case '-':\n return `-${arg}`;\n case '~':\n return `~${arg}`;\n default:\n throw new Error(`unrecognized operation: ${op}`);\n }\n }\n BinarySyntaxTemplate: !!js/function &BinarySyntaxTemplate >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '+':\n return `${s} + ${rhs}`;\n case '-':\n return `${s} - ${rhs}`;\n case '*':\n return `${s} * ${rhs}`;\n case '/':\n return `${s} / ${rhs}`;\n case '**':\n return `${s} ** ${rhs}`;\n case '//':\n return `\\\\intdiv(${s}, ${rhs})`;\n case '%':\n return `${s} % ${rhs}`;\n case '>>':\n return `${s} >> ${rhs}`;\n case '<<':\n return `${s} << ${rhs}`;\n case '|':\n return `${s} | ${rhs}`;\n case '&':\n return `${s} & ${rhs}`;\n case '^':\n return `${s} ^ ${rhs}`;\n default:\n throw new Error(`unrecognized operation: ${op}`);\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosTemplate: &EosSyntaxTemplate null # No args. End-of-line\n EofTemplate: &EofSyntaxTemplate null # No args. End-of-file\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: !!js/function &StringTypeTemplate >\n (str) => {\n // This is some standalone object context, which is generated to parse \n // node and doesn't have access to main Generator object. Thus we can't\n // use utility function call. All ~Template calls use this type of \n // context. All ~ArgsTemplate have access to utility functions.\n\n stringifyWithSingleQuotes = (str) => {\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')\n ) {\n str = str.substr(1, str.length - 2);\n }\n return `'${str.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n };\n\n return `${stringifyWithSingleQuotes(str)}`;\n }\n RegexTypeTemplate: !!js/function &RegexTypeTemplate >\n (pattern, flags) => {\n // This is some standalone object context, which is generated to parse \n // node and doesn't have access to main Generator object. Thus we can't\n // use utility function call. All ~Template calls use this type of \n // context. All ~ArgsTemplate have access to utility functions.\n\n stringifyWithDoubleQuotes = (str) => {\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')\n ) {\n str = str.substr(1, str.length - 2);\n }\n return `${str.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}`;\n };\n\n pattern = `\"${stringifyWithDoubleQuotes(pattern)}\"`;\n flags = flags ? `, \"${flags}\"` : '';\n\n return `new Regex(${pattern}${flags})`;\n }\n BoolTypeTemplate: !!js/function &BoolTypeTemplate >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null # args: literal, argType (i.e. '_string', '_decimal' etc)\n DecimalTypeTemplate: &DecimalTypeTemplate null # args: literal, argType\n LongBasicTypeTemplate: &LongBasicTypeTemplate null # args: literal, argType\n HexTypeTemplate: &HexTypeTemplate null # args: literal, argType\n OctalTypeTemplate: !!js/function &OctalTypeTemplate >\n (literal) => {\n let offset = 0;\n\n if (\n literal.charAt(0) === '0' &&\n (literal.charAt(1) === '0' || literal.charAt(1) === 'o' || literal.charAt(1) === 'O')\n ) {\n offset = 2;\n } else if (literal.charAt(0) === '0') {\n offset = 1;\n }\n\n literal = `0${literal.substr(offset, literal.length - 1)}`;\n\n return literal;\n }\n NumericTypeTemplate: &NumericTypeTemplate null # args: literal, argType\n ArrayTypeTemplate: !!js/function &ArrayTypeTemplate >\n (literal, depth) => {\n if (literal === '') {\n return '[]'\n }\n return `[${literal}]`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null # Args: single array element, nestedness, lastElement? (note: not being used atm)\n NullTypeTemplate: !!js/function &NullTypeTemplate >\n () => {\n return 'null';\n }\n UndefinedTypeTemplate: !!js/function &UndefinedTypeTemplate >\n () => {\n return 'null';\n }\n ObjectTypeTemplate: !!js/function &ObjectTypeTemplate >\n (literal) => {\n return `${literal}`;\n }\n ObjectTypeArgsTemplate: !!js/function &ObjectTypeArgsTemplate >\n (args, depth) => {\n let isObjectCastRequired = true;\n\n if (args.length === 0) {\n return `(object) []`;\n }\n\n const isExpectedIndex = (actualIndex, expectedIndex) => {\n return '' + actualIndex === '' + expectedIndex;\n }\n\n let indexTest = 0;\n let pairs = args.map((arg) => {\n if (isObjectCastRequired && !isExpectedIndex(arg[0], indexTest)) {\n isObjectCastRequired = false;\n }\n indexTest++;\n return `${this.utils.stringifyWithSingleQuotes(arg[0])} => ${arg[1]}`;\n }).join(', ');\n\n // Rebuilding pairs for numeric sequential indexes without quotes\n if (isObjectCastRequired) {\n pairs = args.map((arg) => {\n return `${arg[0]} => ${arg[1]}`;\n }).join(', ');\n }\n\n return `${isObjectCastRequired ? '(object) ' : ''}[${pairs}]`;\n }\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don't take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: !!js/function &CodeSymbolTemplate >\n () => {\n return 'new Javascript';\n }\n CodeSymbolArgsTemplate: !!js/function &CodeSymbolArgsTemplate >\n (lhs, code, scope) => {\n return !scope \n ? `(${this.utils.stringifyWithSingleQuotes(code)})` \n : `(${this.utils.stringifyWithSingleQuotes(code)}, ${scope})`\n ;\n }\n ObjectIdSymbolTemplate: !!js/function &ObjectIdSymbolTemplate >\n () => {\n return 'new ObjectId';\n }\n ObjectIdSymbolArgsTemplate: !!js/function &ObjectIdSymbolArgsTemplate >\n (lhs, id) => {\n return !id \n ? `()` \n : `(${this.utils.stringifyWithSingleQuotes(id)})`\n ;\n }\n BinarySymbolTemplate: !!js/function &BinarySymbolTemplate >\n () => {\n return 'new Binary';\n }\n BinarySymbolArgsTemplate: !!js/function &BinarySymbolArgsTemplate >\n (lhs, bytes, type) => {\n if (type === null) {\n type = 'Binary::TYPE_GENERIC';\n }\n return `(${this.utils.stringifyWithSingleQuotes(bytes)}, ${type})`;\n }\n BinarySymbolSubtypeDefaultTemplate:\n !!js/function &BinarySymbolSubtypeDefaultTemplate >\n () => {\n return 'Binary::TYPE_GENERIC';\n }\n BinarySymbolSubtypeFunctionTemplate:\n !!js/function &BinarySymbolSubtypeFunctionTemplate >\n () => {\n return 'Binary::TYPE_FUNCTION';\n }\n BinarySymbolSubtypeByteArrayTemplate:\n !!js/function &BinarySymbolSubtypeByteArrayTemplate >\n () => {\n return 'Binary::TYPE_OLD_BINARY';\n }\n BinarySymbolSubtypeUuidOldTemplate:\n !!js/function &BinarySymbolSubtypeUuidOldTemplate >\n () => {\n return 'Binary::TYPE_OLD_UUID';\n }\n BinarySymbolSubtypeUuidTemplate:\n !!js/function &BinarySymbolSubtypeUuidTemplate >\n () => {\n return 'Binary::TYPE_UUID';\n }\n BinarySymbolSubtypeMd5Template:\n !!js/function &BinarySymbolSubtypeMd5Template >\n () => {\n return 'Binary::TYPE_MD5';\n }\n BinarySymbolSubtypeUserDefinedTemplate:\n !!js/function &BinarySymbolSubtypeUserDefinedTemplate >\n () => {\n return 'Binary::TYPE_USER_DEFINED';\n }\n DBRefSymbolTemplate: !!js/function &DBRefSymbolTemplate >\n () => {\n return ''\n }\n DBRefSymbolArgsTemplate: !!js/function &DBRefSymbolArgsTemplate >\n (lhs, coll, id, db) => {\n let coll_string = `'$ref' => ${this.utils.stringifyWithSingleQuotes(coll)}`;\n let id_string = `, '$id' => ${id}`;\n let db_string = db ? `, '$db' => ${this.utils.stringifyWithSingleQuotes(db)}` : `, '$db' => null`;\n return `[${coll_string}${id_string}${db_string}]`;\n }\n DoubleSymbolTemplate: !!js/function &DoubleSymbolTemplate >\n () => {\n return '';\n }\n DoubleSymbolArgsTemplate: !!js/function &DoubleSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_decimal' || type === '_double') {\n return arg;\n }\n if (type === '_integer' || type === '_long') {\n return `${arg}.0`;\n }\n return `(float) ${arg}`;\n }\n Int32SymbolTemplate: !!js/function &Int32SymbolTemplate >\n () => {\n return '';\n }\n Int32SymbolArgsTemplate: !!js/function &Int32SymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long' || type === '_hex' || type === '_octal') {\n return arg;\n }\n return `(int) ${arg}`;\n }\n LongSymbolTemplate: !!js/function &LongSymbolTemplate >\n () => {\n return ''\n }\n LongSymbolArgsTemplate: !!js/function &LongSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long' || type === '_hex' || type === '_octal') {\n return arg;\n }\n return `(int) ${arg}`;\n }\n RegExpSymbolTemplate: !!js/function &RegExpSymbolTemplate >\n () => {\n return 'new Regex';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: !!js/function &SymbolSymbolTemplate >\n () => {\n return '';\n }\n SymbolSymbolArgsTemplate: !!js/function &SymbolSymbolArgsTemplate >\n (lhs, arg) => {\n return arg;\n }\n BSONRegExpSymbolTemplate: !!js/function &BSONRegExpSymbolTemplate >\n () => {\n return 'new Regex';\n }\n BSONRegExpSymbolArgsTemplate: !!js/function &BSONRegExpSymbolArgsTemplate >\n (lhs, pattern, flags) => {\n return `(${this.utils.stringifyWithDoubleQuotes(pattern)}${flags ? ', ' + this.utils.stringifyWithDoubleQuotes(flags) : ''})`;\n }\n Decimal128SymbolTemplate: !!js/function &Decimal128SymbolTemplate >\n () => {\n return 'new Decimal128';\n }\n Decimal128SymbolArgsTemplate: !!js/function &Decimal128SymbolArgsTemplate >\n (lhs, arg) => {\n arg = arg === undefined ? '0' : arg.toString();\n return `('${this.utils.removeStringQuotes(arg)}')`;\n }\n MinKeySymbolTemplate: !!js/function &MinKeySymbolTemplate >\n () => {\n return 'new MinKey';\n }\n MinKeySymbolArgsTemplate: !!js/function &MinKeySymbolArgsTemplate >\n () => {\n return `()`;\n }\n MaxKeySymbolTemplate: !!js/function &MaxKeySymbolTemplate >\n () => {\n return 'new MaxKey';\n }\n MaxKeySymbolArgsTemplate: !!js/function &MaxKeySymbolArgsTemplate >\n () => {\n return `()`;\n }\n TimestampSymbolTemplate: !!js/function &TimestampSymbolTemplate >\n () => {\n return 'new Timestamp';\n }\n TimestampSymbolArgsTemplate: !!js/function &TimestampSymbolArgsTemplate >\n (lhs, arg1, arg2) => {\n // PHP orders increment and timestamp args differently (see: PHPC-845)\n return `(${arg2 === undefined ? 0 : arg2}, ${arg1 === undefined ? 0 : arg1})`;\n }\n # non bson-specific\n NumberSymbolTemplate: !!js/function &NumberSymbolTemplate >\n () => ''\n NumberSymbolArgsTemplate: !!js/function &NumberSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n switch(type) {\n case '_string':\n if ((arg.indexOf('.') !== -1) && (arg.indexOf('.') !== arg.length - 2)) {\n return `(float) ${arg}`\n }\n return `(int) ${arg}`\n default:\n return `${arg}`\n }\n }\n DateSymbolTemplate: !!js/function &DateSymbolTemplate >\n () => {\n return 'UTCDateTime';\n }\n DateSymbolArgsTemplate: !!js/function &DateSymbolArgsTemplate >\n (lhs, date, isString) => {\n if (date === null) {\n return `new ${lhs}()`;\n }\n return isString \n ? `(new ${lhs}(${date.getTime()}))->toDateTime()->format(\\\\DateTimeInterface::RFC3339_EXTENDED)`\n : `new ${lhs}(${date.getTime()})`\n ;\n }\n DateSymbolNowTemplate: !!js/function &DateSymbolNowTemplate >\n () => {\n return `new UTCDateTime()`;\n }\n DateSymbolNowArgsTemplate: !!js/function &DateSymbolNowArgsTemplate >\n (args) => {\n return '';\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These're variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: !!js/function &CodeCodeTemplate >\n (lhs) => {\n return `(${lhs})->getCode()`;\n }\n CodeCodeArgsTemplate: !!js/function &CodeCodeArgsTemplate >\n () => {\n return '';\n }\n CodeScopeTemplate: !!js/function &CodeScopeTemplate >\n (lhs) => {\n return `(${lhs})->getScope()`;\n }\n CodeScopeArgsTemplate: !!js/function &CodeScopeArgsTemplate >\n () => {\n return '';\n }\n ObjectIdToStringTemplate: !!js/function &ObjectIdToStringTemplate >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n ObjectIdToStringArgsTemplate: !!js/function &ObjectIdToStringArgsTemplate >\n () => {\n return '';\n }\n ObjectIdEqualsTemplate: !!js/function &ObjectIdEqualsTemplate >\n (lhs) => {\n return `${lhs} == `;\n }\n ObjectIdEqualsArgsTemplate: !!js/function &ObjectIdEqualsArgsTemplate >\n (arg) => {\n return `${arg}`;\n }\n ObjectIdGetTimestampTemplate: !!js/function &ObjectIdGetTimestampTemplate >\n (lhs) => {\n return `(${lhs})->getTimestamp()`;\n }\n ObjectIdGetTimestampArgsTemplate:\n !!js/function &ObjectIdGetTimestampArgsTemplate >\n () => {\n return '';\n }\n ObjectIdIsValidTemplate: !!js/function &ObjectIdIsValidTemplate >\n (lhs) => {\n return ``;\n }\n ObjectIdIsValidArgsTemplate: !!js/function &ObjectIdIsValidArgsTemplate >\n (lhs, arg) => {\n return `(\\\\ctype_xdigit(${this.utils.stringifyWithSingleQuotes(arg)}) && \\\\strlen(${this.utils.stringifyWithSingleQuotes(arg)}) == 24)`;\n }\n BinaryValueTemplate: !!js/function &BinaryValueTemplate >\n (lhs) => {\n return `(${lhs})->getData()`;\n }\n BinaryValueArgsTemplate: !!js/function &BinaryValueArgsTemplate >\n () => {\n return '';\n }\n BinaryLengthTemplate: !!js/function &BinaryLengthTemplate >\n (lhs) => {\n return `\\\\strlen((${lhs})->getData())`;\n }\n BinaryLengthArgsTemplate: !!js/function &BinaryLengthArgsTemplate >\n () => {\n return '';\n }\n BinaryToStringTemplate: !!js/function &BinaryToStringTemplate >\n (lhs) => {\n return `(${lhs})->getData()`;\n }\n BinaryToStringArgsTemplate: !!js/function &BinaryToStringArgsTemplate >\n () => {\n return '';\n }\n BinarySubtypeTemplate: !!js/function &BinarySubtypeTemplate >\n (lhs) => {\n return `(${lhs})->getType()`;\n }\n BinarySubtypeArgsTemplate: !!js/function &BinarySubtypeArgsTemplate >\n () => {\n return '';\n }\n DBRefGetDBTemplate: !!js/function &DBRefGetDBTemplate >\n (lhs) => {\n return `${lhs}['$db']`;\n }\n DBRefGetCollectionTemplate: !!js/function &DBRefGetCollectionTemplate >\n (lhs) => {\n return `${lhs}['$ref']`;\n }\n DBRefGetIdTemplate: !!js/function &DBRefGetIdTemplate >\n (lhs) => {\n return `${lhs}['$id']`;\n }\n DBRefGetDBArgsTemplate: !!js/function &DBRefGetDBArgsTemplate >\n (lhs) => {\n return '';\n }\n DBRefGetCollectionArgsTemplate:\n !!js/function &DBRefGetCollectionArgsTemplate >\n (lhs) => {\n return '';\n }\n DBRefGetIdArgsTemplate: !!js/function &DBRefGetIdArgsTemplate >\n (lhs) => {\n return '';\n }\n DBRefToStringTemplate: &DBRefToStringTemplate null\n DBRefToStringArgsTemplate: &DBRefToStringArgsTemplate null\n DoubleValueOfTemplate: &DoubleValueOfTemplate null\n DoubleValueOfArgsTemplate: &DoubleValueOfArgsTemplate null\n Int32ValueOfTemplate: &Int32ValueOfTemplate null\n Int32ValueOfArgsTemplate: &Int32ValueOfArgsTemplate null\n Int32ToStringTemplate: !!js/function &Int32ToStringTemplate >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n Int32ToStringArgsTemplate: !!js/function &Int32ToStringArgsTemplate >\n () => {\n return '';\n }\n LongEqualsTemplate: !!js/function &LongEqualsTemplate >\n (lhs) => {\n return `${lhs} ==`;\n }\n LongEqualsArgsTemplate: !!js/function &LongEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongToStringTemplate: !!js/function &LongToStringTemplate >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n LongToStringArgsTemplate: !!js/function &LongToStringArgsTemplate >\n () => {\n return '';\n }\n LongToIntTemplate: !!js/function &LongToIntTemplate >\n (lhs) => {\n return `${lhs}`;\n }\n LongToIntArgsTemplate: !!js/function &LongToIntArgsTemplate >\n () => {\n return '';\n }\n LongValueOfTemplate: &LongValueOfTemplate null\n LongValueOfArgsTemplate: &LongValueOfArgsTemplate null\n LongToNumberTemplate: !!js/function &LongToNumberTemplate >\n (lhs) => {\n return `(float) ${lhs}`;\n }\n LongToNumberArgsTemplate: !!js/function &LongToNumberArgsTemplate >\n () => {\n return '';\n }\n LongAddTemplate: !!js/function &LongAddTemplate >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: !!js/function &LongAddArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: !!js/function &LongSubtractTemplate >\n (arg) => {\n return `${arg} -`;\n }\n LongSubtractArgsTemplate: !!js/function &LongSubtractArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: !!js/function &LongMultiplyTemplate >\n (arg) => {\n return `${arg} *`;\n }\n LongMultiplyArgsTemplate: !!js/function &LongMultiplyArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: !!js/function &LongDivTemplate >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: !!js/function &LongDivArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: !!js/function &LongModuloTemplate >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: !!js/function &LongModuloArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: !!js/function &LongAndTemplate >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: !!js/function &LongAndArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: !!js/function &LongOrTemplate >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: !!js/function &LongOrArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: !!js/function &LongXorTemplate >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: !!js/function &LongXorArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: !!js/function &LongShiftLeftTemplate >\n (lhs) => {\n return `${lhs} <<`;\n }\n LongShiftLeftArgsTemplate: !!js/function &LongShiftLeftArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftRightTemplate: !!js/function &LongShiftRightTemplate >\n (lhs) => {\n return `${lhs} >>`;\n }\n LongShiftRightArgsTemplate: !!js/function &LongShiftRightArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongCompareTemplate: !!js/function &LongCompareTemplate >\n (lhs) => {\n return `${lhs} <=>`;\n }\n LongCompareArgsTemplate: !!js/function &LongCompareArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongIsOddTemplate: !!js/function &LongIsOddTemplate >\n (lhs) => {\n return `(${lhs} % 2) === 1`;\n }\n LongIsOddArgsTemplate: !!js/function &LongIsOddArgsTemplate >\n () => {\n return '';\n }\n LongIsZeroTemplate: !!js/function &LongIsZeroTemplate >\n (lhs) => {\n return `${lhs} === 0`;\n }\n LongIsZeroArgsTemplate: !!js/function &LongIsZeroArgsTemplate >\n () => {\n return '';\n }\n LongIsNegativeTemplate: !!js/function &LongIsNegativeTemplate >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: !!js/function &LongIsNegativeArgsTemplate >\n () => {\n return '';\n }\n LongNegateTemplate: !!js/function &LongNegateTemplate >\n () => {\n return '-';\n }\n LongNegateArgsTemplate: !!js/function &LongNegateArgsTemplate >\n (lhs) => {\n return lhs;\n }\n LongNotTemplate: !!js/function &LongNotTemplate >\n () => {\n return '~';\n }\n LongNotArgsTemplate: !!js/function &LongNotArgsTemplate >\n (lhs) => {\n return lhs;\n }\n LongNotEqualsTemplate: !!js/function &LongNotEqualsTemplate >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: !!js/function &LongNotEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: !!js/function &LongGreaterThanTemplate >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: !!js/function &LongGreaterThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate:\n !!js/function &LongGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate:\n !!js/function &LongGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: !!js/function &LongLessThanTemplate >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: !!js/function &LongLessThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: !!js/function &LongLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate:\n !!js/function &LongLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: !!js/function &LongFloatApproxTemplate >\n (lhs) => {\n return `(float) ${lhs}`;\n }\n LongTopTemplate: !!js/function &LongTopTemplate >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: !!js/function &LongBottomTemplate >\n (lhs) => {\n return `${lhs} & 0x00000000ffffffff`;\n }\n TimestampToStringTemplate: !!js/function &TimestampToStringTemplate >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n TimestampToStringArgsTemplate: !!js/function &TimestampToStringArgsTemplate >\n () => {\n return '';\n }\n TimestampEqualsTemplate: !!js/function &TimestampEqualsTemplate >\n (lhs) => {\n return `${lhs} == `;\n }\n TimestampEqualsArgsTemplate: !!js/function &TimestampEqualsArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGetLowBitsTemplate: !!js/function &TimestampGetLowBitsTemplate >\n (lhs) => {\n return `(${lhs})->getTimestamp()`;\n }\n TimestampGetLowBitsArgsTemplate:\n !!js/function &TimestampGetLowBitsArgsTemplate >\n () => {\n return ''\n }\n TimestampGetHighBitsTemplate: !!js/function &TimestampGetHighBitsTemplate >\n (lhs) => {\n return `(${lhs})->getIncrement()`;\n }\n TimestampGetHighBitsArgsTemplate:\n !!js/function &TimestampGetHighBitsArgsTemplate >\n () => {\n return ''\n }\n TimestampTTemplate: !!js/function &TimestampTTemplate >\n (lhs) => {\n return `(${lhs})->getTimestamp()`;\n }\n TimestampITemplate: !!js/function &TimestampITemplate >\n (lhs) => {\n return `(${lhs})->getIncrement()`;\n }\n TimestampAsDateTemplate: !!js/function &TimestampAsDateTemplate >\n (lhs) => {\n return `new UTCDateTime((${lhs})->getTimestamp() * 1000)`;\n }\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate null\n TimestampCompareTemplate: !!js/function &TimestampCompareTemplate >\n (lhs) => {\n return `${lhs} <=> `;\n }\n TimestampCompareArgsTemplate: !!js/function &TimestampCompareArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampNotEqualsTemplate: !!js/function &TimestampNotEqualsTemplate >\n (lhs) => {\n return `${lhs} != `;\n }\n TimestampNotEqualsArgsTemplate:\n !!js/function &TimestampNotEqualsArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanTemplate: !!js/function &TimestampGreaterThanTemplate >\n (lhs) => {\n return `${lhs} > `;\n }\n TimestampGreaterThanArgsTemplate:\n !!js/function &TimestampGreaterThanArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanOrEqualTemplate:\n !!js/function &TimestampGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} >= `;\n }\n TimestampGreaterThanOrEqualArgsTemplate:\n !!js/function &TimestampGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanTemplate: !!js/function &TimestampLessThanTemplate >\n (lhs) => {\n return `${lhs} < `;\n }\n TimestampLessThanArgsTemplate: !!js/function &TimestampLessThanArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanOrEqualTemplate:\n !!js/function &TimestampLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} <= `;\n }\n TimestampLessThanOrEqualArgsTemplate:\n !!js/function &TimestampLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n SymbolValueOfTemplate: !!js/function &SymbolValueOfTemplate >\n (lhs) => {\n return lhs;\n }\n SymbolValueOfArgsTemplate: !!js/function &SymbolValueOfArgsTemplate >\n () => {\n return '';\n }\n SymbolInspectTemplate: !!js/function &SymbolInspectTemplate >\n (lhs) => {\n return lhs;\n }\n SymbolInspectArgsTemplate: !!js/function &SymbolInspectArgsTemplate >\n () => {\n return '';\n }\n SymbolToStringTemplate: !!js/function &SymbolToStringTemplate >\n (lhs) => {\n return lhs;\n }\n SymbolToStringArgsTemplate: !!js/function &SymbolToStringArgsTemplate >\n (lhs) => {\n return '';\n }\n Decimal128ToStringTemplate: !!js/function &Decimal128ToStringTemplate >\n (lhs) => {\n return `(string) ${lhs}`;\n }\n Decimal128ToStringArgsTemplate:\n !!js/function &Decimal128ToStringArgsTemplate >\n (lhs) => {\n return '';\n }\n\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These're variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don't overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: !!js/function &LongSymbolMaxTemplate >\n () => {\n return '\\\\PHP_INT_MAX';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: !!js/function &LongSymbolMinTemplate >\n () => {\n return '\\\\PHP_INT_MIN';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: !!js/function &LongSymbolZeroTemplate >\n () => {\n return '0';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: !!js/function &LongSymbolOneTemplate >\n () => {\n return '1';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: !!js/function &LongSymbolNegOneTemplate >\n () => {\n return '-1';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: !!js/function &LongSymbolFromBitsTemplate >\n () => {\n return '';\n }\n LongSymbolFromBitsArgsTemplate:\n !!js/function &LongSymbolFromBitsArgsTemplate >\n (lhs, arg) => {\n return `(int) ${arg}`;\n }\n LongSymbolFromIntTemplate: !!js/function &LongSymbolFromIntTemplate >\n () => {\n return '';\n }\n LongSymbolFromIntArgsTemplate: !!js/function &LongSymbolFromIntArgsTemplate >\n (lhs, arg) => {\n return arg;\n }\n LongSymbolFromNumberTemplate: !!js/function &LongSymbolFromNumberTemplate >\n () => {\n return '';\n }\n LongSymbolFromNumberArgsTemplate:\n !!js/function &LongSymbolFromNumberArgsTemplate >\n (lhs, arg) => {\n return `(int) ${arg}`;\n }\n LongSymbolFromStringTemplate: !!js/function &LongSymbolFromStringTemplate >\n () => {\n return '';\n }\n LongSymbolFromStringArgsTemplate:\n !!js/function &LongSymbolFromStringArgsTemplate >\n (lhs, arg) => {\n return `(int) ${arg}`;\n }\n Decimal128SymbolFromStringTemplate:\n !!js/function &Decimal128SymbolFromStringTemplate >\n () => {\n return 'new Decimal128';\n }\n Decimal128SymbolFromStringArgsTemplate:\n !!js/function &Decimal128SymbolFromStringArgsTemplate >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromHexStringTemplate:\n !!js/function &ObjectIdCreateFromHexStringTemplate >\n () => {\n return 'new ObjectId';\n }\n ObjectIdCreateFromHexStringArgsTemplate:\n !!js/function &ObjectIdCreateFromHexStringArgsTemplate >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromTimeTemplate:\n !!js/function &ObjectIdCreateFromTimeTemplate >\n () => {\n return 'new ObjectId';\n }\n ObjectIdCreateFromTimeArgsTemplate:\n !!js/function &ObjectIdCreateFromTimeArgsTemplate >\n (lhs, arg, isNumber) => {\n if (!isNumber) {\n return `(\\\\str_pad(\\\\bin2hex(\\\\pack('N', (${arg})->toDateTime()->getTimestamp())), 24, '0'))`;\n }\n return `(\\\\str_pad(\\\\bin2hex(\\\\pack('N', ${arg})), 24, '0'))`;\n }\n # non bson-specific would go here, but there aren't any atm.\n #############################################\n # Imports #\n # #\n # Each type has a 'code' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: !!js/function &ImportTemplate >\n (args) => {\n let set = new Set(Object.values(args));\n return [...set].sort().join('\\n');\n }\n DriverImportTemplate: !!js/function &DriverImportTemplate >\n () => {\n return `use MongoDB\\\\Client;`;\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n # Common internal Regexp\n 8ImportTemplate: !!js/function &8ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\Regex;`;\n }\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n # Code\n 100ImportTemplate: !!js/function &100ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\Javascript;`;\n }\n # ObjectId\n 101ImportTemplate: !!js/function &101ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\ObjectId;`;\n }\n # Binary\n 102ImportTemplate: !!js/function &102ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\Binary;`;\n }\n # DBRef\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n # Int64\n 106ImportTemplate: &106ImportTemplate null\n # MinKey\n 107ImportTemplate: !!js/function &107ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\MinKey;`;\n }\n # MaxKey\n 108ImportTemplate: !!js/function &108ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\MaxKey;`;\n }\n # Regex\n 109ImportTemplate: !!js/function &109ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\Regex;`;\n }\n # Timestamp\n 110ImportTemplate: !!js/function &110ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\Timestamp;`;\n }\n 111ImportTemplate: &111ImportTemplate null\n # Decimal128\n 112ImportTemplate: !!js/function &112ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\Decimal128;`;\n }\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: !!js/function &200ImportTemplate >\n () => {\n return `use MongoDB\\\\BSON\\\\UTCDateTime;`;\n }\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; diff --git a/packages/bson-transpilers/lib/symbol-table/shelltopython.js b/packages/bson-transpilers/lib/symbol-table/shelltopython.js index 71c05719a5a..65596d08dc0 100644 --- a/packages/bson-transpilers/lib/symbol-table/shelltopython.js +++ b/packages/bson-transpilers/lib/symbol-table/shelltopython.js @@ -1 +1,2 @@ -module.exports="SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n\n# Python Templates\nTemplates:\n # Misc\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'a'\n y: ''\n g: 's'\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n # Syntax\n\n # filter, project, sort, collation, skip, limit, maxTimeMS\n DriverTemplate: &DriverTemplate !!js/function >\n (spec) => {\n const comment = `# Requires the PyMongo package.\n # https://api.mongodb.com/python/current`;\n const translateKey = {\n filter: 'filter',\n project: 'projection',\n sort: 'sort',\n collation: 'collation',\n skip: 'skip',\n limit: 'limit',\n maxTimeMS: 'max_time_ms'\n };\n const options = spec.options;\n const exportMode = spec.exportMode;\n delete spec.options;\n delete spec.exportMode;\n\n const connect = `client = MongoClient('${options.uri}')`;\n const coll = `client['${options.database}']['${options.collection}']`;\n\n let driverMethod;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'delete_many';\n break;\n case 'Update Query':\n driverMethod = 'update_many';\n break;\n default:\n driverMethod = 'find';\n }\n\n if ('aggregation' in spec) {\n return `${comment}\\n\\n${connect}\\nresult = ${coll}.aggregate(${spec.aggregation})`;\n }\n\n const vars = Object.keys(spec).reduce(\n (result, k) => {\n if (k === 'sort') {\n return `${result}\\n${k}=list(${spec[k]}.items())`;\n }\n return `${result}\\n${k}=${spec[k]}`;\n },\n connect\n );\n\n const args = Object.keys(spec).reduce(\n (result, k) => {\n const divider = result === '' ? '' : ',\\n';\n return `${result}${divider} ${\n k in translateKey ? translateKey[k] : k\n }=${k}`;\n },\n ''\n );\n const cmd = `result = ${coll}.${driverMethod}(\\n${args}\\n)`;\n\n return `${comment}\\n\\n${vars}\\n\\n${cmd}`;\n }\n EqualitySyntaxTemplate: &EqualitySyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n if (op.includes('!')) {\n return `${lhs} != ${rhs}`;\n }\n else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: &InSyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n let str = 'in';\n if (op.includes('!') || op.includes('not')) {\n str = 'not in';\n }\n return `${lhs} ${str} ${rhs}`\n }\n AndSyntaxTemplate: &AndSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' and ');\n }\n OrSyntaxTemplate: &OrSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' or ');\n }\n NotSyntaxTemplate: &NotSyntaxTemplate !!js/function >\n (arg) => {\n return `not ${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: &BinarySyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `${s} // ${rhs}`;\n case '**':\n return `${s} ** ${rhs}`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosSyntaxTemplate: &EosSyntaxTemplate null\n EofSyntaxTemplate: &EofSyntaxTemplate null\n NewTemplate: &NewSyntaxTemplate null\n # BSON Object Type templates\n CodeTypeTemplate: &CodeTypeTemplate null\n StringTypeTemplate: &StringTypeTemplate !!js/function >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}'`;\n }\n RegexTypeTemplate: &RegexTypeTemplate !!js/function >\n (pattern, flags) => {\n flags = flags === '' ? '' : `(?${flags})`;\n const escaped = pattern.replace(/\\\\(?!\\/)/, '\\\\\\\\');\n\n // Double-quote stringify\n const str = escaped + flags;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `re.compile(r\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n BoolTypeTemplate: &BoolTypeTemplate !!js/function >\n (str) => {\n return `${str.charAt(0).toUpperCase()}${str.slice(1)}`;\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null\n DecimalTypeTemplate: &DecimalTypeTemplate null\n LongBasicTypeTemplate: &LongBasicTypeTemplate null\n HexTypeTemplate: &HexTypeTemplate null\n OctalTypeTemplate: &OctalTypeTemplate !!js/function >\n (literal) => {\n let offset = 0;\n\n if (\n literal.charAt(0) === '0' &&\n (literal.charAt(1) === '0' || literal.charAt(1) === 'o' || literal.charAt(1) === 'O')\n ) {\n offset = 2;\n } else if (literal.charAt(0) === '0') {\n offset = 1;\n }\n\n literal = `0o${literal.substr(offset, literal.length - 1)}`;\n\n return literal;\n }\n NumericTypeTemplate: &NumericTypeTemplate null\n ArrayTypeTemplate: &ArrayTypeTemplate !!js/function >\n (literal, depth) => {\n depth++;\n if (literal === '') {\n return '[]'\n }\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n\n return `[${indent}${literal}${closingIndent}]`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null\n NullTypeTemplate: &NullTypeTemplate !!js/function >\n () => {\n return 'None';\n }\n UndefinedTypeTemplate: &UndefinedTypeTemplate !!js/function >\n () => {\n return 'None';\n }\n ObjectTypeTemplate: &ObjectTypeTemplate !!js/function >\n (literal, depth) => {\n if (literal === '') {\n return '{}';\n }\n return literal;\n }\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate !!js/function >\n (args, depth) => {\n if (args.length === 0) {\n return '{}';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}'`;\n }\n\n const pairs = args.map((arg) => {\n return `${indent}${singleStringify(arg[0])}: ${arg[1]}`;\n }).join(', ');\n\n return `{${pairs}${closingIndent}}`;\n }\n # BSON Object Method templates\n CodeCodeTemplate: &CodeCodeTemplate !!js/function >\n (lhs) => {\n return `str(${lhs})`;\n }\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate null\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate !!js/function >\n (lhs) => {\n return `str(${lhs})`;\n }\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} ==`;\n }\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate !!js/function >\n (lhs) => {\n return `${lhs}.generation_time`;\n }\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate !!js/function >\n () => {\n return '';\n }\n BinaryValueTemplate: &BinaryValueTemplate !!js/function >\n () => {\n return '';\n }\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate !!js/function >\n (lhs) => {\n return `str(${lhs})`;\n }\n BinaryLengthTemplate: &BinaryLengthTemplate !!js/function >\n () => {\n return '';\n }\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate !!js/function >\n (lhs) => {\n return `len(${lhs})`;\n }\n BinaryToStringTemplate: &BinaryToStringTemplate !!js/function >\n () => {\n return '';\n }\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate !!js/function >\n (lhs) => {\n return `str(${lhs})`;\n }\n BinarySubtypeTemplate: &BinarySubtypeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.subtype`;\n }\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate null\n DBRefGetDBTemplate: &DBRefGetDBTemplate !!js/function >\n (lhs) => {\n return `${lhs}.database`;\n }\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate !!js/function >\n (lhs) => {\n return `${lhs}.collection`;\n }\n DBRefGetIdTemplate: &DBRefGetIdTemplate !!js/function >\n (lhs) => {\n return `${lhs}.id`;\n }\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate !!js/function\n () => {\n return '';\n }\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate !!js/function >\n () => {\n return '';\n }\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate !!js/function\n () => {\n return '';\n }\n LongEqualsTemplate: &LongEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} ==`;\n }\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongToIntTemplate: &LongToIntTemplate !!js/function >\n (lhs) => {\n return `int(${lhs})`;\n }\n LongToIntArgsTemplate: &LongToIntArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongToStringTemplate: &LongToStringTemplate !!js/function >\n () => {\n return 'str';\n }\n LongToStringArgsTemplate: &LongToStringArgsTemplate !!js/function >\n (lhs) => {\n return `(${lhs})`;\n }\n LongToNumberTemplate: &LongToNumberTemplate !!js/function >\n (lhs) => {\n return `float(${lhs})`;\n }\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongAddTemplate: &LongAddTemplate !!js/function >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: &LongAddArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: &LongSubtractTemplate !!js/function >\n (arg) => {\n return `${arg} -`;\n }\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: &LongMultiplyTemplate !!js/function >\n (arg) => {\n return `${arg} *`;\n }\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: &LongDivTemplate !!js/function >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: &LongDivArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: &LongModuloTemplate !!js/function >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: &LongModuloArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: &LongAndTemplate !!js/function >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: &LongAndArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: &LongOrTemplate !!js/function >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: &LongOrArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: &LongXorTemplate !!js/function >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: &LongXorArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: &LongShiftLeftTemplate !!js/function >\n (lhs) => {\n return `${lhs} <<`;\n }\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftRightTemplate: &LongShiftRightTemplate !!js/function >\n (lhs) => {\n return `${lhs} >>`;\n }\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongCompareTemplate: &LongCompareTemplate !!js/function >\n (lhs) => {\n return `${lhs} -`;\n }\n LongCompareArgsTemplate: &LongCompareArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongIsOddTemplate: &LongIsOddTemplate !!js/function >\n (lhs) => {\n return `(${lhs} % 2) == 1`;\n }\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongIsZeroTemplate: &LongIsZeroTemplate !!js/function >\n (lhs) => {\n return `${lhs} == 0`;\n }\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongIsNegativeTemplate: &LongIsNegativeTemplate !!js/function >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongNegateTemplate: &LongNegateTemplate !!js/function >\n () => {\n return '-';\n }\n LongNegateArgsTemplate: &LongNegateArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongNotTemplate: &LongNotTemplate !!js/function >\n () => {\n return '~';\n }\n LongNotArgsTemplate: &LongNotArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongNotEqualsTemplate: &LongNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: &LongGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: &LongLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: &LongFloatApproxTemplate !!js/function >\n (lhs) => {\n return `float(${lhs})`;\n }\n LongTopTemplate: &LongTopTemplate !!js/function >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: &LongBottomTemplate !!js/function >\n (lhs) => {\n return `${lhs} & 0x0000ffff`;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate !!js/function >\n () => {\n return 'str';\n }\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate !!js/function >\n (lhs) => {\n return `(${lhs})`;\n }\n TimestampEqualsTemplate: &TimestampEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} ==`;\n }\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampGetLowBitsTemplate: &TimestampGetLowBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.time`;\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate !!js/function >\n () => {\n return '';\n }\n TimestampGetHighBitsTemplate: &TimestampGetHighBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.inc`;\n }\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate !!js/function >\n () => {\n return '';\n }\n TimestampTTemplate: &TimestampTTemplate !!js/function >\n (lhs) => {\n return `${lhs}.time`;\n }\n TimestampITemplate: &TimestampITemplate !!js/function >\n (lhs) => {\n return `${lhs}.inc`;\n }\n TimestampAsDateTemplate: &TimestampAsDateTemplate null\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate !!js/function >\n () => {\n return '.as_datetime()';\n }\n TimestampCompareTemplate: &TimestampCompareTemplate !!js/function >\n (lhs) => {\n return `(${lhs}.as_datetime() - `;\n }\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}.as_datetime()).total_seconds()`;\n }\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} !=`;\n }\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} >`;\n }\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} >=`;\n }\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampLessThanTemplate: &TimestampLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} <`;\n }\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} <=`;\n }\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n SymbolValueOfTemplate: &SymbolValueOfTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate !!js/function >\n () => {\n return '';\n }\n SymbolInspectTemplate: &SymbolInspectTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate !!js/function >\n () => {\n return '';\n }\n SymbolToStringTemplate: &SymbolToStringTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n # Symbol Templates\n CodeSymbolTemplate: &CodeSymbolTemplate !!js/function > # Also has process method\n () => {\n return 'Code';\n }\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate !!js/function > # Also has process method\n (lhs, code, scope) => {\n // Single quote stringify\n const scopestr = scope === undefined ? '' : `, ${scope}`;\n let newStr = code === undefined ? '' : code;\n const str = newStr;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n code = `'${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}'`;\n return `(${code}${scopestr})`;\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate null\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate !!js/function >\n (lhs, str) => {\n if (!str || str.length === 0) {\n return '()';\n }\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `('${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}')`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate !!js/function >\n (lhs, bytes, type) => {\n const str = bytes;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n bytes = `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n\n if (type === null) {\n return `(b${bytes})`;\n }\n return `(b${bytes}, ${type})`;\n }\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate !!js/function >\n () => {\n return 'binary.BINARY_SUBTYPE';\n }\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate !!js/function >\n () => {\n return 'binary.FUNCTION_SUBTYPE';\n }\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate !!js/function >\n () => {\n return 'binary.BINARY_SUBTYPE';\n }\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate !!js/function >\n () => {\n return 'binary.OLD_UUID_SUBTYPE';\n }\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate !!js/function >\n () => {\n return 'binary.UUID_SUBTYPE';\n }\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template !!js/function >\n () => {\n return 'binary.MD5_SUBTYPE';\n }\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate !!js/function >\n () => {\n return 'binary.USER_DEFINED_SUBTYPE';\n }\n DBRefSymbolTemplate: &DBRefSymbolTemplate null\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null\n DoubleSymbolTemplate: &DoubleSymbolTemplate !!js/function >\n () => {\n return 'float';\n }\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate null\n Int32SymbolTemplate: &Int32SymbolTemplate !!js/function >\n () => {\n return 'int';\n }\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n arg = arg === undefined ? 0 : arg;\n const str = arg.toString();\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n return `('${newStr}')`;\n } else {\n return `(${newStr})`;\n }\n }\n LongSymbolTemplate: &LongSymbolTemplate !!js/function >\n () => {\n return 'Int64';\n }\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate null\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate !!js/function >\n () => {\n return 'sys.maxsize';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate !!js/function >\n () => {\n return '-sys.maxsize -1';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate !!js/function >\n () => {\n return 'Int64(0)';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate !!js/function >\n () => {\n return 'Int64(1)';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate !!js/function >\n () => {\n return 'Int64(-1)';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate !!js/function > # Also has process method\n () => {\n return 'Int64';\n }\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate !!js/function >\n () => {\n return 'Int64';\n }\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate null\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate !!js/function >\n () => {\n return 'Int64';\n }\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate !!js/function >\n (lhs, arg) => {\n return 'Int64';\n }\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(int(${arg}))`;\n }\n MinKeySymbolTemplate: &MinKeySymbolTemplate null\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate null\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate null\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate null\n TimestampSymbolTemplate: &TimestampSymbolTemplate !!js/function >\n () => {\n return 'Timestamp';\n }\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate !!js/function >\n (lhs, arg1, arg2) => {\n return `(${arg1 === undefined ? 0 : arg1}, ${arg2 === undefined ? 0 : arg2})`;\n }\n SymbolSymbolTemplate: &SymbolSymbolTemplate !!js/function >\n () => {\n return '';\n }\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n return arg;\n }\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate !!js/function >\n () => {\n return 'Regex';\n }\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate !!js/function >\n (lhs, pattern, flags) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}'`;\n }\n return `(${singleStringify(pattern)}${flags ? ', ' + singleStringify(flags) : ''})`;\n }\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate !!js/function >\n () => {\n return 'Decimal128';\n }\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate !!js/function >\n (lhs, str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `('${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}')`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate !!js/function >\n () => {\n return 'Decimal128';\n }\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg})`;\n }\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate !!js/function >\n () => {\n return 'str';\n }\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate !!js/function >\n (lhs) => {\n return `(${lhs})`;\n }\n # BSON Util Templates\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate !!js/function >\n () => {\n return 'ObjectId';\n }\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate !!js/function >\n () => {\n return `ObjectId.from_datetime`;\n }\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate !!js/function >\n (lhs, arg, isNumber) => {\n if (isNumber) {\n return `(datetime.fromtimestamp(${arg}))`;\n }\n return `(${arg})`;\n }\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate !!js/function >\n (lhs) => {\n return `${lhs}.is_valid`;\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n # JS Symbol Templates\n NumberSymbolTemplate: &NumberSymbolTemplate !!js/function >\n () => {\n return '';\n }\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n arg = arg === undefined ? 0 : arg;\n const str = arg.toString();\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n return `float('${newStr}')`;\n } else {\n return `${newStr}`;\n }\n }\n DateSymbolTemplate: &DateSymbolTemplate !!js/function >\n () => {\n return 'datetime';\n }\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate !!js/function >\n (lhs, date, isString) => {\n const toStr = isString ? '.strftime(\\'%a %b %d %Y %H:%M:%S %Z\\')' : '';\n\n if (date === null) {\n return `${lhs}.utcnow()${toStr}`;\n }\n\n const dateStr = [\n date.getUTCFullYear(),\n date.getUTCMonth() + 1,\n date.getUTCDate(),\n date.getUTCHours(),\n date.getUTCMinutes(),\n date.getUTCSeconds()\n ].join(', ');\n\n return `${lhs}(${dateStr}, tzinfo=timezone.utc)${toStr}`;\n }\n DateSymbolNowTemplate: &DateSymbolNowTemplate !!js/function >\n () => {\n return 'datetime.utcnow';\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate null\n RegExpSymbolTemplate: &RegExpSymbolTemplate !!js/function > # Also has process method\n () => {\n return 're';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null\n ImportTemplate: &ImportTemplate !!js/function >\n (args) => {\n const bson = [];\n const other = [];\n Object.keys(args).map(\n (m) => {\n if (m > 99 && m < 200) {\n bson.push(args[m]);\n } else {\n other.push(args[m]);\n }\n }\n );\n if (bson.length) {\n other.push(`from bson import ${bson.join(', ')}`);\n }\n return other.join('\\n');\n }\n DriverImportTemplate: &DriverImportTemplate !!js/function >\n () => {\n return 'from pymongo import MongoClient';\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate !!js/function >\n () => {\n return 'import re';\n }\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: &100ImportTemplate !!js/function >\n () => {\n return 'Code';\n }\n 101ImportTemplate: &101ImportTemplate !!js/function >\n () => {\n return 'ObjectId';\n }\n 102ImportTemplate: &102ImportTemplate !!js/function >\n () => {\n return 'Binary';\n }\n 103ImportTemplate: &103ImportTemplate !!js/function >\n () => {\n return 'DBRef';\n }\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate !!js/function >\n () => {\n return 'Int64';\n }\n 107ImportTemplate: &107ImportTemplate !!js/function >\n () => {\n return 'MinKey';\n }\n 108ImportTemplate: &108ImportTemplate !!js/function >\n () => {\n return 'MaxKey';\n }\n 109ImportTemplate: &109ImportTemplate !!js/function >\n () => {\n return 'Regex';\n }\n 110ImportTemplate: &110ImportTemplate !!js/function >\n () => {\n return 'Timestamp';\n }\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: &112ImportTemplate !!js/function >\n () => {\n return 'Decimal128';\n }\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate !!js/function >\n () => {\n return 'from datetime import datetime, tzinfo, timezone';\n }\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; +module.exports = + "SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n# Python Templates\nTemplates:\n # Misc\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'a'\n y: ''\n g: 's'\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n # Syntax\n\n # filter, project, sort, collation, skip, limit, maxTimeMS\n DriverTemplate: !!js/function &DriverTemplate >\n (spec) => {\n const comment = `# Requires the PyMongo package.\n # https://api.mongodb.com/python/current`;\n const translateKey = {\n filter: 'filter',\n project: 'projection',\n sort: 'sort',\n collation: 'collation',\n skip: 'skip',\n limit: 'limit',\n maxTimeMS: 'max_time_ms'\n };\n const options = spec.options;\n const exportMode = spec.exportMode;\n delete spec.options;\n delete spec.exportMode;\n\n const connect = `client = MongoClient('${options.uri}')`;\n const coll = `client['${options.database}']['${options.collection}']`;\n\n let driverMethod;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'delete_many';\n break;\n case 'Update Query':\n driverMethod = 'update_many';\n break;\n default:\n driverMethod = 'find';\n }\n\n if ('aggregation' in spec) {\n return `${comment}\\n\\n${connect}\\nresult = ${coll}.aggregate(${spec.aggregation})`;\n }\n\n const vars = Object.keys(spec).reduce(\n (result, k) => {\n if (k === 'sort') {\n return `${result}\\n${k}=list(${spec[k]}.items())`;\n }\n return `${result}\\n${k}=${spec[k]}`;\n },\n connect\n );\n\n const args = Object.keys(spec).reduce(\n (result, k) => {\n const divider = result === '' ? '' : ',\\n';\n return `${result}${divider} ${\n k in translateKey ? translateKey[k] : k\n }=${k}`;\n },\n ''\n );\n const cmd = `result = ${coll}.${driverMethod}(\\n${args}\\n)`;\n\n return `${comment}\\n\\n${vars}\\n\\n${cmd}`;\n }\n EqualitySyntaxTemplate: !!js/function &EqualitySyntaxTemplate >\n (lhs, op, rhs) => {\n if (op.includes('!')) {\n return `${lhs} != ${rhs}`;\n }\n else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: !!js/function &InSyntaxTemplate >\n (lhs, op, rhs) => {\n let str = 'in';\n if (op.includes('!') || op.includes('not')) {\n str = 'not in';\n }\n return `${lhs} ${str} ${rhs}`\n }\n AndSyntaxTemplate: !!js/function &AndSyntaxTemplate >\n (args) => {\n return args.join(' and ');\n }\n OrSyntaxTemplate: !!js/function &OrSyntaxTemplate >\n (args) => {\n return args.join(' or ');\n }\n NotSyntaxTemplate: !!js/function &NotSyntaxTemplate >\n (arg) => {\n return `not ${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: !!js/function &BinarySyntaxTemplate >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `${s} // ${rhs}`;\n case '**':\n return `${s} ** ${rhs}`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosSyntaxTemplate: &EosSyntaxTemplate null\n EofSyntaxTemplate: &EofSyntaxTemplate null\n NewTemplate: &NewSyntaxTemplate null\n # BSON Object Type templates\n CodeTypeTemplate: &CodeTypeTemplate null\n StringTypeTemplate: !!js/function &StringTypeTemplate >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}'`;\n }\n RegexTypeTemplate: !!js/function &RegexTypeTemplate >\n (pattern, flags) => {\n flags = flags === '' ? '' : `(?${flags})`;\n\n // Double-quote stringify\n const str = pattern + flags;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `re.compile(r\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\")`;\n }\n BoolTypeTemplate: !!js/function &BoolTypeTemplate >\n (str) => {\n return `${str.charAt(0).toUpperCase()}${str.slice(1)}`;\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null\n DecimalTypeTemplate: &DecimalTypeTemplate null\n LongBasicTypeTemplate: &LongBasicTypeTemplate null\n HexTypeTemplate: &HexTypeTemplate null\n OctalTypeTemplate: !!js/function &OctalTypeTemplate >\n (literal) => {\n let offset = 0;\n\n if (\n literal.charAt(0) === '0' &&\n (literal.charAt(1) === '0' || literal.charAt(1) === 'o' || literal.charAt(1) === 'O')\n ) {\n offset = 2;\n } else if (literal.charAt(0) === '0') {\n offset = 1;\n }\n\n literal = `0o${literal.substr(offset, literal.length - 1)}`;\n\n return literal;\n }\n NumericTypeTemplate: &NumericTypeTemplate null\n ArrayTypeTemplate: !!js/function &ArrayTypeTemplate >\n (literal, depth) => {\n depth++;\n if (literal === '') {\n return '[]'\n }\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n\n return `[${indent}${literal}${closingIndent}]`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null\n NullTypeTemplate: !!js/function &NullTypeTemplate >\n () => {\n return 'None';\n }\n UndefinedTypeTemplate: !!js/function &UndefinedTypeTemplate >\n () => {\n return 'None';\n }\n ObjectTypeTemplate: !!js/function &ObjectTypeTemplate >\n (literal, depth) => {\n if (literal === '') {\n return '{}';\n }\n return literal;\n }\n ObjectTypeArgsTemplate: !!js/function &ObjectTypeArgsTemplate >\n (args, depth) => {\n if (args.length === 0) {\n return '{}';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}'`;\n }\n\n const pairs = args.map((arg) => {\n return `${indent}${singleStringify(arg[0])}: ${arg[1]}`;\n }).join(', ');\n\n return `{${pairs}${closingIndent}}`;\n }\n # BSON Object Method templates\n CodeCodeTemplate: !!js/function &CodeCodeTemplate >\n (lhs) => {\n return `str(${lhs})`;\n }\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate null\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: !!js/function &ObjectIdToStringTemplate >\n (lhs) => {\n return `str(${lhs})`;\n }\n ObjectIdToStringArgsTemplate: !!js/function &ObjectIdToStringArgsTemplate >\n (lhs) => {\n return '';\n }\n ObjectIdEqualsTemplate: !!js/function &ObjectIdEqualsTemplate >\n (lhs) => {\n return `${lhs} ==`;\n }\n ObjectIdEqualsArgsTemplate: !!js/function &ObjectIdEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n ObjectIdGetTimestampTemplate: !!js/function &ObjectIdGetTimestampTemplate >\n (lhs) => {\n return `${lhs}.generation_time`;\n }\n ObjectIdGetTimestampArgsTemplate:\n !!js/function &ObjectIdGetTimestampArgsTemplate >\n () => {\n return '';\n }\n BinaryValueTemplate: !!js/function &BinaryValueTemplate >\n () => {\n return '';\n }\n BinaryValueArgsTemplate: !!js/function &BinaryValueArgsTemplate >\n (lhs) => {\n return `str(${lhs})`;\n }\n BinaryLengthTemplate: !!js/function &BinaryLengthTemplate >\n () => {\n return '';\n }\n BinaryLengthArgsTemplate: !!js/function &BinaryLengthArgsTemplate >\n (lhs) => {\n return `len(${lhs})`;\n }\n BinaryToStringTemplate: !!js/function &BinaryToStringTemplate >\n () => {\n return '';\n }\n BinaryToStringArgsTemplate: !!js/function &BinaryToStringArgsTemplate >\n (lhs) => {\n return `str(${lhs})`;\n }\n BinarySubtypeTemplate: !!js/function &BinarySubtypeTemplate >\n (lhs) => {\n return `${lhs}.subtype`;\n }\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate null\n DBRefGetDBTemplate: !!js/function &DBRefGetDBTemplate >\n (lhs) => {\n return `${lhs}.database`;\n }\n DBRefGetCollectionTemplate: !!js/function &DBRefGetCollectionTemplate >\n (lhs) => {\n return `${lhs}.collection`;\n }\n DBRefGetIdTemplate: !!js/function &DBRefGetIdTemplate >\n (lhs) => {\n return `${lhs}.id`;\n }\n DBRefGetIdArgsTemplate: !!js/function &DBRefGetIdArgsTemplate () => {\n return '';\n }\n DBRefGetDBArgsTemplate: !!js/function &DBRefGetDBArgsTemplate >\n () => {\n return '';\n }\n DBRefGetCollectionArgsTemplate:\n !!js/function &DBRefGetCollectionArgsTemplate () => {\n return '';\n }\n LongEqualsTemplate: !!js/function &LongEqualsTemplate >\n (lhs) => {\n return `${lhs} ==`;\n }\n LongEqualsArgsTemplate: !!js/function &LongEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongToIntTemplate: !!js/function &LongToIntTemplate >\n (lhs) => {\n return `int(${lhs})`;\n }\n LongToIntArgsTemplate: !!js/function &LongToIntArgsTemplate >\n () => {\n return '';\n }\n LongToStringTemplate: !!js/function &LongToStringTemplate >\n () => {\n return 'str';\n }\n LongToStringArgsTemplate: !!js/function &LongToStringArgsTemplate >\n (lhs) => {\n return `(${lhs})`;\n }\n LongToNumberTemplate: !!js/function &LongToNumberTemplate >\n (lhs) => {\n return `float(${lhs})`;\n }\n LongToNumberArgsTemplate: !!js/function &LongToNumberArgsTemplate >\n () => {\n return '';\n }\n LongAddTemplate: !!js/function &LongAddTemplate >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: !!js/function &LongAddArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: !!js/function &LongSubtractTemplate >\n (arg) => {\n return `${arg} -`;\n }\n LongSubtractArgsTemplate: !!js/function &LongSubtractArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: !!js/function &LongMultiplyTemplate >\n (arg) => {\n return `${arg} *`;\n }\n LongMultiplyArgsTemplate: !!js/function &LongMultiplyArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: !!js/function &LongDivTemplate >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: !!js/function &LongDivArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: !!js/function &LongModuloTemplate >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: !!js/function &LongModuloArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: !!js/function &LongAndTemplate >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: !!js/function &LongAndArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: !!js/function &LongOrTemplate >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: !!js/function &LongOrArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: !!js/function &LongXorTemplate >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: !!js/function &LongXorArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: !!js/function &LongShiftLeftTemplate >\n (lhs) => {\n return `${lhs} <<`;\n }\n LongShiftLeftArgsTemplate: !!js/function &LongShiftLeftArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftRightTemplate: !!js/function &LongShiftRightTemplate >\n (lhs) => {\n return `${lhs} >>`;\n }\n LongShiftRightArgsTemplate: !!js/function &LongShiftRightArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongCompareTemplate: !!js/function &LongCompareTemplate >\n (lhs) => {\n return `${lhs} -`;\n }\n LongCompareArgsTemplate: !!js/function &LongCompareArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongIsOddTemplate: !!js/function &LongIsOddTemplate >\n (lhs) => {\n return `(${lhs} % 2) == 1`;\n }\n LongIsOddArgsTemplate: !!js/function &LongIsOddArgsTemplate >\n () => {\n return '';\n }\n LongIsZeroTemplate: !!js/function &LongIsZeroTemplate >\n (lhs) => {\n return `${lhs} == 0`;\n }\n LongIsZeroArgsTemplate: !!js/function &LongIsZeroArgsTemplate >\n () => {\n return '';\n }\n LongIsNegativeTemplate: !!js/function &LongIsNegativeTemplate >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: !!js/function &LongIsNegativeArgsTemplate >\n () => {\n return '';\n }\n LongNegateTemplate: !!js/function &LongNegateTemplate >\n () => {\n return '-';\n }\n LongNegateArgsTemplate: !!js/function &LongNegateArgsTemplate >\n (lhs) => {\n return lhs;\n }\n LongNotTemplate: !!js/function &LongNotTemplate >\n () => {\n return '~';\n }\n LongNotArgsTemplate: !!js/function &LongNotArgsTemplate >\n (lhs) => {\n return lhs;\n }\n LongNotEqualsTemplate: !!js/function &LongNotEqualsTemplate >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: !!js/function &LongNotEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: !!js/function &LongGreaterThanTemplate >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: !!js/function &LongGreaterThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate:\n !!js/function &LongGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate:\n !!js/function &LongGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: !!js/function &LongLessThanTemplate >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: !!js/function &LongLessThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: !!js/function &LongLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate:\n !!js/function &LongLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: !!js/function &LongFloatApproxTemplate >\n (lhs) => {\n return `float(${lhs})`;\n }\n LongTopTemplate: !!js/function &LongTopTemplate >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: !!js/function &LongBottomTemplate >\n (lhs) => {\n return `${lhs} & 0x0000ffff`;\n }\n TimestampToStringTemplate: !!js/function &TimestampToStringTemplate >\n () => {\n return 'str';\n }\n TimestampToStringArgsTemplate: !!js/function &TimestampToStringArgsTemplate >\n (lhs) => {\n return `(${lhs})`;\n }\n TimestampEqualsTemplate: !!js/function &TimestampEqualsTemplate >\n (lhs) => {\n return `${lhs} ==`;\n }\n TimestampEqualsArgsTemplate: !!js/function &TimestampEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampGetLowBitsTemplate: !!js/function &TimestampGetLowBitsTemplate >\n (lhs) => {\n return `${lhs}.time`;\n }\n TimestampGetLowBitsArgsTemplate:\n !!js/function &TimestampGetLowBitsArgsTemplate >\n () => {\n return '';\n }\n TimestampGetHighBitsTemplate: !!js/function &TimestampGetHighBitsTemplate >\n (lhs) => {\n return `${lhs}.inc`;\n }\n TimestampGetHighBitsArgsTemplate:\n !!js/function &TimestampGetHighBitsArgsTemplate >\n () => {\n return '';\n }\n TimestampTTemplate: !!js/function &TimestampTTemplate >\n (lhs) => {\n return `${lhs}.time`;\n }\n TimestampITemplate: !!js/function &TimestampITemplate >\n (lhs) => {\n return `${lhs}.inc`;\n }\n TimestampAsDateTemplate: &TimestampAsDateTemplate null\n TimestampAsDateArgsTemplate: !!js/function &TimestampAsDateArgsTemplate >\n () => {\n return '.as_datetime()';\n }\n TimestampCompareTemplate: !!js/function &TimestampCompareTemplate >\n (lhs) => {\n return `(${lhs}.as_datetime() - `;\n }\n TimestampCompareArgsTemplate: !!js/function &TimestampCompareArgsTemplate >\n (lhs, arg) => {\n return `${arg}.as_datetime()).total_seconds()`;\n }\n TimestampNotEqualsTemplate: !!js/function &TimestampNotEqualsTemplate >\n (lhs) => {\n return `${lhs} !=`;\n }\n TimestampNotEqualsArgsTemplate:\n !!js/function &TimestampNotEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampGreaterThanTemplate: !!js/function &TimestampGreaterThanTemplate >\n (lhs) => {\n return `${lhs} >`;\n }\n TimestampGreaterThanArgsTemplate:\n !!js/function &TimestampGreaterThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampGreaterThanOrEqualTemplate:\n !!js/function &TimestampGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} >=`;\n }\n TimestampGreaterThanOrEqualArgsTemplate:\n !!js/function &TimestampGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampLessThanTemplate: !!js/function &TimestampLessThanTemplate >\n (lhs) => {\n return `${lhs} <`;\n }\n TimestampLessThanArgsTemplate: !!js/function &TimestampLessThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n TimestampLessThanOrEqualTemplate:\n !!js/function &TimestampLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} <=`;\n }\n TimestampLessThanOrEqualArgsTemplate:\n !!js/function &TimestampLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n SymbolValueOfTemplate: !!js/function &SymbolValueOfTemplate >\n (lhs) => {\n return lhs;\n }\n SymbolValueOfArgsTemplate: !!js/function &SymbolValueOfArgsTemplate >\n () => {\n return '';\n }\n SymbolInspectTemplate: !!js/function &SymbolInspectTemplate >\n (lhs) => {\n return lhs;\n }\n SymbolInspectArgsTemplate: !!js/function &SymbolInspectArgsTemplate >\n () => {\n return '';\n }\n SymbolToStringTemplate: !!js/function &SymbolToStringTemplate >\n (lhs) => {\n return lhs;\n }\n SymbolToStringArgsTemplate: !!js/function &SymbolToStringArgsTemplate >\n () => {\n return '';\n }\n # Symbol Templates\n CodeSymbolTemplate:\n !!js/function &CodeSymbolTemplate > # Also has process method\n () => {\n return 'Code';\n }\n CodeSymbolArgsTemplate:\n !!js/function &CodeSymbolArgsTemplate > # Also has process method\n (lhs, code, scope) => {\n // Single quote stringify\n const scopestr = scope === undefined ? '' : `, ${scope}`;\n let newStr = code === undefined ? '' : code;\n const str = newStr;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n code = `'${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}'`;\n return `(${code}${scopestr})`;\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate null\n ObjectIdSymbolArgsTemplate: !!js/function &ObjectIdSymbolArgsTemplate >\n (lhs, str) => {\n if (!str || str.length === 0) {\n return '()';\n }\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `('${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}')`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: !!js/function &BinarySymbolArgsTemplate >\n (lhs, bytes, type) => {\n const str = bytes;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n bytes = `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n\n if (type === null) {\n return `(b${bytes})`;\n }\n return `(b${bytes}, ${type})`;\n }\n BinarySymbolSubtypeDefaultTemplate:\n !!js/function &BinarySymbolSubtypeDefaultTemplate >\n () => {\n return 'binary.BINARY_SUBTYPE';\n }\n BinarySymbolSubtypeFunctionTemplate:\n !!js/function &BinarySymbolSubtypeFunctionTemplate >\n () => {\n return 'binary.FUNCTION_SUBTYPE';\n }\n BinarySymbolSubtypeByteArrayTemplate:\n !!js/function &BinarySymbolSubtypeByteArrayTemplate >\n () => {\n return 'binary.BINARY_SUBTYPE';\n }\n BinarySymbolSubtypeUuidOldTemplate:\n !!js/function &BinarySymbolSubtypeUuidOldTemplate >\n () => {\n return 'binary.OLD_UUID_SUBTYPE';\n }\n BinarySymbolSubtypeUuidTemplate:\n !!js/function &BinarySymbolSubtypeUuidTemplate >\n () => {\n return 'binary.UUID_SUBTYPE';\n }\n BinarySymbolSubtypeMd5Template:\n !!js/function &BinarySymbolSubtypeMd5Template >\n () => {\n return 'binary.MD5_SUBTYPE';\n }\n BinarySymbolSubtypeUserDefinedTemplate:\n !!js/function &BinarySymbolSubtypeUserDefinedTemplate >\n () => {\n return 'binary.USER_DEFINED_SUBTYPE';\n }\n DBRefSymbolTemplate: &DBRefSymbolTemplate null\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null\n DoubleSymbolTemplate: !!js/function &DoubleSymbolTemplate >\n () => {\n return 'float';\n }\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate null\n Int32SymbolTemplate: !!js/function &Int32SymbolTemplate >\n () => {\n return 'int';\n }\n Int32SymbolArgsTemplate: !!js/function &Int32SymbolArgsTemplate >\n (lhs, arg) => {\n arg = arg === undefined ? 0 : arg;\n const str = arg.toString();\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n return `('${newStr}')`;\n } else {\n return `(${newStr})`;\n }\n }\n LongSymbolTemplate: !!js/function &LongSymbolTemplate >\n () => {\n return 'Int64';\n }\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate null\n LongSymbolMaxTemplate: !!js/function &LongSymbolMaxTemplate >\n () => {\n return 'sys.maxsize';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: !!js/function &LongSymbolMinTemplate >\n () => {\n return '-sys.maxsize -1';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: !!js/function &LongSymbolZeroTemplate >\n () => {\n return 'Int64(0)';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: !!js/function &LongSymbolOneTemplate >\n () => {\n return 'Int64(1)';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: !!js/function &LongSymbolNegOneTemplate >\n () => {\n return 'Int64(-1)';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate:\n !!js/function &LongSymbolFromBitsTemplate > # Also has process method\n () => {\n return 'Int64';\n }\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: !!js/function &LongSymbolFromIntTemplate >\n () => {\n return 'Int64';\n }\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate null\n LongSymbolFromNumberTemplate: !!js/function &LongSymbolFromNumberTemplate >\n () => {\n return 'Int64';\n }\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: !!js/function &LongSymbolFromStringTemplate >\n (lhs, arg) => {\n return 'Int64';\n }\n LongSymbolFromStringArgsTemplate:\n !!js/function &LongSymbolFromStringArgsTemplate >\n (lhs, arg) => {\n return `(int(${arg}))`;\n }\n MinKeySymbolTemplate: &MinKeySymbolTemplate null\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate null\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate null\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate null\n TimestampSymbolTemplate: !!js/function &TimestampSymbolTemplate >\n () => {\n return 'Timestamp';\n }\n TimestampSymbolArgsTemplate: !!js/function &TimestampSymbolArgsTemplate >\n (lhs, arg1, arg2) => {\n return `(${arg1 === undefined ? 0 : arg1}, ${arg2 === undefined ? 0 : arg2})`;\n }\n SymbolSymbolTemplate: !!js/function &SymbolSymbolTemplate >\n () => {\n return '';\n }\n SymbolSymbolArgsTemplate: !!js/function &SymbolSymbolArgsTemplate >\n (lhs, arg) => {\n return arg;\n }\n BSONRegExpSymbolTemplate: !!js/function &BSONRegExpSymbolTemplate >\n () => {\n return 'Regex';\n }\n BSONRegExpSymbolArgsTemplate: !!js/function &BSONRegExpSymbolArgsTemplate >\n (lhs, pattern, flags) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}'`;\n }\n return `(${singleStringify(pattern)}${flags ? ', ' + singleStringify(flags) : ''})`;\n }\n Decimal128SymbolTemplate: !!js/function &Decimal128SymbolTemplate >\n () => {\n return 'Decimal128';\n }\n Decimal128SymbolArgsTemplate: !!js/function &Decimal128SymbolArgsTemplate >\n (lhs, str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `('${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}')`;\n }\n Decimal128SymbolFromStringTemplate:\n !!js/function &Decimal128SymbolFromStringTemplate >\n () => {\n return 'Decimal128';\n }\n Decimal128SymbolFromStringArgsTemplate:\n !!js/function &Decimal128SymbolFromStringArgsTemplate >\n (lhs, arg) => {\n return `(${arg})`;\n }\n Decimal128ToStringTemplate: !!js/function &Decimal128ToStringTemplate >\n () => {\n return 'str';\n }\n Decimal128ToStringArgsTemplate:\n !!js/function &Decimal128ToStringArgsTemplate >\n (lhs) => {\n return `(${lhs})`;\n }\n # BSON Util Templates\n ObjectIdCreateFromHexStringTemplate:\n !!js/function &ObjectIdCreateFromHexStringTemplate >\n () => {\n return 'ObjectId';\n }\n ObjectIdCreateFromHexStringArgsTemplate:\n !!js/function &ObjectIdCreateFromHexStringArgsTemplate >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromTimeTemplate:\n !!js/function &ObjectIdCreateFromTimeTemplate >\n () => {\n return `ObjectId.from_datetime`;\n }\n ObjectIdCreateFromTimeArgsTemplate:\n !!js/function &ObjectIdCreateFromTimeArgsTemplate >\n (lhs, arg, isNumber) => {\n if (isNumber) {\n return `(datetime.fromtimestamp(${arg}))`;\n }\n return `(${arg})`;\n }\n ObjectIdIsValidTemplate: !!js/function &ObjectIdIsValidTemplate >\n (lhs) => {\n return `${lhs}.is_valid`;\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n # JS Symbol Templates\n NumberSymbolTemplate: !!js/function &NumberSymbolTemplate >\n () => {\n return '';\n }\n NumberSymbolArgsTemplate: !!js/function &NumberSymbolArgsTemplate >\n (lhs, arg) => {\n arg = arg === undefined ? 0 : arg;\n const str = arg.toString();\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n return `float('${newStr}')`;\n } else {\n return `${newStr}`;\n }\n }\n DateSymbolTemplate: !!js/function &DateSymbolTemplate >\n () => {\n return 'datetime';\n }\n DateSymbolArgsTemplate: !!js/function &DateSymbolArgsTemplate >\n (lhs, date, isString) => {\n const toStr = isString ? '.strftime(\\'%a %b %d %Y %H:%M:%S %Z\\')' : '';\n\n if (date === null) {\n return `${lhs}.utcnow()${toStr}`;\n }\n\n const dateStr = [\n date.getUTCFullYear(),\n date.getUTCMonth() + 1,\n date.getUTCDate(),\n date.getUTCHours(),\n date.getUTCMinutes(),\n date.getUTCSeconds()\n ].join(', ');\n\n return `${lhs}(${dateStr}, tzinfo=timezone.utc)${toStr}`;\n }\n DateSymbolNowTemplate: !!js/function &DateSymbolNowTemplate >\n () => {\n return 'datetime.utcnow';\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate null\n RegExpSymbolTemplate:\n !!js/function &RegExpSymbolTemplate > # Also has process method\n () => {\n return 're';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null\n ImportTemplate: !!js/function &ImportTemplate >\n (args) => {\n const bson = [];\n const other = [];\n Object.keys(args).map(\n (m) => {\n if (m > 99 && m < 200) {\n bson.push(args[m]);\n } else {\n other.push(args[m]);\n }\n }\n );\n if (bson.length) {\n other.push(`from bson import ${bson.join(', ')}`);\n }\n return other.join('\\n');\n }\n DriverImportTemplate: !!js/function &DriverImportTemplate >\n () => {\n return 'from pymongo import MongoClient';\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: !!js/function &8ImportTemplate >\n () => {\n return 'import re';\n }\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: !!js/function &100ImportTemplate >\n () => {\n return 'Code';\n }\n 101ImportTemplate: !!js/function &101ImportTemplate >\n () => {\n return 'ObjectId';\n }\n 102ImportTemplate: !!js/function &102ImportTemplate >\n () => {\n return 'Binary';\n }\n 103ImportTemplate: !!js/function &103ImportTemplate >\n () => {\n return 'DBRef';\n }\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: !!js/function &106ImportTemplate >\n () => {\n return 'Int64';\n }\n 107ImportTemplate: !!js/function &107ImportTemplate >\n () => {\n return 'MinKey';\n }\n 108ImportTemplate: !!js/function &108ImportTemplate >\n () => {\n return 'MaxKey';\n }\n 109ImportTemplate: !!js/function &109ImportTemplate >\n () => {\n return 'Regex';\n }\n 110ImportTemplate: !!js/function &110ImportTemplate >\n () => {\n return 'Timestamp';\n }\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: !!js/function &112ImportTemplate >\n () => {\n return 'Decimal128';\n }\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: !!js/function &200ImportTemplate >\n () => {\n return 'from datetime import datetime, tzinfo, timezone';\n }\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; diff --git a/packages/bson-transpilers/lib/symbol-table/shelltoruby.js b/packages/bson-transpilers/lib/symbol-table/shelltoruby.js index befe7023ee2..a7295ccd687 100644 --- a/packages/bson-transpilers/lib/symbol-table/shelltoruby.js +++ b/packages/bson-transpilers/lib/symbol-table/shelltoruby.js @@ -1 +1,2 @@ -module.exports="SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace 'null' with '!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: ''\n y: ''\n g: ''\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: ''\n l: ''\n u: ''\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: &DriverTemplate !!js/function >\n (spec) => {\n comment = '# Requires the MongoDB Ruby Driver\\n# https://docs.mongodb.com/ruby-driver/master/';\n\n const getKey = k => {\n let translateKey = {\n project: 'projection',\n maxTimeMS: 'max_time_ms'\n }\n return k in translateKey ? translateKey[k] : k\n };\n const options = spec.options;\n const filter = spec.filter || {}\n const exportMode = spec.exportMode;\n\n delete spec.options;\n delete spec.filter\n delete spec.exportMode;\n\n const connect = `client = Mongo::Client.new('${options.uri}', :database => '${options.database}')`;\n const coll = `client.database['${options.collection}']`;\n\n let driverMethod;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'delete_many';\n break;\n case 'Update Query':\n driverMethod = 'update_many';\n break;\n default:\n driverMethod = 'find';\n }\n\n if ('aggregation' in spec) {\n return `${comment}\\n\\n${connect}\\nresult = ${coll}.aggregate(${spec.aggregation})`;\n }\n\n const vars = Object.keys(spec).reduce(\n (result, k) => {\n return `${result}\\n${getKey(k)} = ${spec[k]}`;\n },\n connect\n );\n\n const args = Object.keys(spec).reduce(\n (result, k) => {\n const divider = result === '' ? '' : ',\\n';\n return `${result}${divider} ${getKey(k)}: ${getKey(k)}`;\n },\n ''\n );\n\n const cmd = `result = ${coll}.${driverMethod}(${filter}${args ? `, {\\n${args}\\n}` : ''})`;\n\n return `${comment}\\n\\n${vars}\\n\\n${cmd}`;\n }\n EqualitySyntaxTemplate: &EqualitySyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n if (op.includes('is')) {\n let not = op.includes('not') ? '!' : ''\n return `${not}${lhs}.equal?(${rhs})`\n } else if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n } else if (op === '==' || op === '===') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: &InSyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n let str = '';\n if (op.includes('!') || op.includes('not')) {\n str = '!';\n }\n return `${str}${rhs}.include?(${lhs})`\n }\n AndSyntaxTemplate: &AndSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: &OrSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: &NotSyntaxTemplate !!js/function >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: &BinarySyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `${s}.div(${rhs})`;\n case '**':\n return `${s} ** ${rhs}`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosTemplate: &EosSyntaxTemplate null # No args. End-of-line\n EofTemplate: &EofSyntaxTemplate null # No args. End-of-file\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: &StringTypeTemplate !!js/function >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n RegexTypeTemplate: &RegexTypeTemplate !!js/function >\n (pattern, flags) => {\n const str = pattern;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n pattern = `${newStr.replace(/\\\\([\\s\\S])/g, '\\\\$1')}`;\n return `/${pattern}/${flags ? flags : ''}`;\n }\n BoolTypeTemplate: &BoolTypeTemplate !!js/function >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null # args: literal, argType (i.e. '_string', '_decimal' etc)\n DecimalTypeTemplate: &DecimalTypeTemplate null # args: literal, argType\n LongBasicTypeTemplate: &LongBasicTypeTemplate null # args: literal, argType\n HexTypeTemplate: &HexTypeTemplate null # args: literal, argType\n OctalTypeTemplate: &OctalTypeTemplate !!js/function >\n (literal) => {\n let offset = 0;\n\n if (\n literal.charAt(0) === '0' &&\n (literal.charAt(1) === '0' || literal.charAt(1) === 'o' || literal.charAt(1) === 'O')\n ) {\n offset = 2;\n } else if (literal.charAt(0) === '0') {\n offset = 1;\n }\n\n literal = `0o${literal.substr(offset, literal.length - 1)}`;\n\n return literal;\n }\n NumericTypeTemplate: &NumericTypeTemplate null # args: literal, argType\n ArrayTypeTemplate: &ArrayTypeTemplate !!js/function >\n (literal, depth) => {\n depth++;\n if (literal === '') {\n return '[]'\n }\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n\n return `[${indent}${literal}${closingIndent}]`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null # Args: single array element, nestedness, lastElement? (note: not being used atm)\n NullTypeTemplate: &NullTypeTemplate !!js/function >\n () => {\n return 'nil';\n }\n UndefinedTypeTemplate: &UndefinedTypeTemplate !!js/function >\n () => {\n return 'nil';\n }\n ObjectTypeTemplate: &ObjectTypeTemplate !!js/function >\n (literal) => {\n if (literal === '') {\n return '{}';\n }\n return literal;\n }\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate !!js/function >\n (args, depth) => {\n if (args.length === 0) {\n return '{}';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n const pairs = args.map((arg) => {\n return `${indent}${singleStringify(arg[0])} => ${arg[1]}`;\n }).join(',');\n\n return `{${pairs}${closingIndent}}`\n }\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don't take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: &CodeSymbolTemplate !!js/function >\n () => {\n return 'BSON::Code'\n }\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate !!js/function >\n (lhs, code, scope) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n if (code === undefined) {\n return '.new'\n }\n return !scope ? `.new(${singleStringify(code)})` : `WithScope.new(${singleStringify(code)}, ${scope})`\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate !!js/function >\n () => {\n return 'BSON::ObjectId';\n }\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate !!js/function >\n (lhs, id) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n return !id ? '.new' : `(${singleStringify(id)})`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate null\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate null\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate null\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate null\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate null\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate null\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template null\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate null\n DBRefSymbolTemplate: &DBRefSymbolTemplate !!js/function >\n () => {\n return 'BSON::DBRef'\n }\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate !!js/function >\n (lhs, coll, id, db) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n\n let db_string = db ? `,\\n '$db' => ${singleStringify(db)}` : ''\n return `.new(\\n '$ref' => ${singleStringify(coll)},\\n '$id' => ${id}${db_string}\\n)`\n }\n DoubleSymbolTemplate: &DoubleSymbolTemplate !!js/function >\n () => {\n return '';\n }\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_decimal' || type === '_double') {\n return arg;\n }\n return `${arg}.to_f`;\n }\n Int32SymbolTemplate: &Int32SymbolTemplate !!js/function >\n () => {\n return '';\n }\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long') {\n return arg;\n }\n return `${arg}.to_i`;\n }\n LongSymbolTemplate: &LongSymbolTemplate !!js/function >\n () => {\n return ''\n }\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long') {\n return arg;\n }\n return `${arg}.to_i`;\n }\n RegExpSymbolTemplate: &RegExpSymbolTemplate !!js/function >\n () => {\n return '';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: &SymbolSymbolTemplate !!js/function >\n () => {\n return '';\n }\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n arg = arg === undefined ? '' : arg;\n const str = arg.toString();\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n return `:'${newStr}'`;\n } else {\n return `${newStr}.to_sym`;\n }\n }\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate !!js/function >\n () => {\n return '';\n }\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate !!js/function >\n (lhs, pattern, flags) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `${newStr.replace(/\\\\([\\s\\S])/g, '\\\\$1')}`;\n }\n return `/${singleStringify(pattern)}/${flags ? singleStringify(flags) : ''}`;\n }\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate !!js/function >\n () => {\n return 'BSON::Decimal128';\n }\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n arg = arg === undefined ? '0' : arg.toString();\n if (arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'') {\n return `.new(${arg})`;\n }\n return `.new('${arg}')`;\n }\n MinKeySymbolTemplate: &MinKeySymbolTemplate !!js/function >\n () => {\n return 'BSON::MinKey';\n }\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate !!js/function >\n () => {\n return '.new';\n }\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate !!js/function >\n () => {\n return 'BSON::MaxKey';\n }\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate !!js/function >\n () => {\n return '.new';\n }\n TimestampSymbolTemplate: &TimestampSymbolTemplate !!js/function >\n () => {\n return 'BSON::Timestamp';\n }\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate !!js/function >\n (lhs, arg1, arg2) => {\n return `.new(${arg1 === undefined ? 0 : arg1}, ${arg2 === undefined ? 0 : arg2})`;\n }\n # non bson-specific\n NumberSymbolTemplate: &NumberSymbolTemplate !!js/function >\n () => {\n return '';\n }\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n const str = arg.toString();\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n return `'${newStr}'.to_f`;\n } else if (type === '_decimal' || type === '_double') {\n return newStr;\n } else {\n return `${newStr}.to_f`;\n }\n }\n DateSymbolTemplate: &DateSymbolTemplate !!js/function >\n () => {\n return 'Time';\n }\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate !!js/function >\n (lhs, date, isString) => {\n const toStr = isString ? '.strftime(\\'%a %b %d %Y %H:%M:%S %Z\\')' : '';\n\n if (date === null) {\n return `${lhs}.new.utc${toStr}`;\n }\n\n const dateStr = [\n date.getUTCFullYear(),\n date.getUTCMonth() + 1,\n date.getUTCDate(),\n date.getUTCHours(),\n date.getUTCMinutes(),\n date.getUTCSeconds()\n ].join(', ');\n\n return `${lhs}.utc(${dateStr})${toStr}`;\n }\n\n DateSymbolNowTemplate: &DateSymbolNowTemplate !!js/function >\n () => {\n return 'Time.now.utc';\n }\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate !!js/function >\n (args) => {\n return '';\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These're variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: &CodeCodeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.javascript`;\n }\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate !!js/function >\n () => {\n return '';\n }\n CodeScopeTemplate: &CodeScopeTemplate !!js/function >\n (lhs) => {\n return `${lhs}.scope`;\n }\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate !!js/function >\n () => {\n return '';\n }\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.to_s`;\n }\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} == `;\n }\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate !!js/function >\n (arg) => {\n return `${arg}`;\n }\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate !!js/function >\n (lhs) => {\n return `${lhs}.to_time`;\n }\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate !!js/function >\n () => {\n return '';\n }\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate !!js/function >\n (lhs) => {\n return `${lhs}.legal?`\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate null\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: &BinarySubtypeTemplate null\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate null\n DBRefGetDBTemplate: &DBRefGetDBTemplate !!js/function >\n (lhs) => {\n return `${lhs}.database`;\n }\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate !!js/function >\n (lhs) => {\n return `${lhs}.collection`;\n }\n DBRefGetIdTemplate: &DBRefGetIdTemplate !!js/function >\n (lhs) => {\n return `${lhs}.id`;\n }\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n DBRefToStringTemplate: &DBRefToStringTemplate !!js/function >\n (lhs) => {\n return '${lhs}.to_s';\n }\n DBRefToStringArgsTemplate: &DBRefToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n DoubleValueOfTemplate: &DoubleValueOfTemplate null\n DoubleValueOfArgsTemplate: &DoubleValueOfArgsTemplate null\n Int32ValueOfTemplate: &Int32ValueOfTemplate null\n Int32ValueOfArgsTemplate: &Int32ValueOfArgsTemplate null\n Int32ToStringTemplate: &Int32ToStringTemplate null\n Int32ToStringArgsTemplate: &Int32ToStringArgsTemplate null\n LongEqualsTemplate: &LongEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} ==`;\n }\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongToIntTemplate: &LongToIntTemplate !!js/function >\n (lhs) => {\n return `${lhs}`;\n }\n LongToIntArgsTemplate: &LongToIntArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongToStringTemplate: &LongToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.to_s`;\n }\n LongToStringArgsTemplate: &LongToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongToNumberTemplate: &LongToNumberTemplate !!js/function >\n (lhs) => {\n return `${lhs}.to_f`;\n }\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongAddTemplate: &LongAddTemplate !!js/function >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: &LongAddArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: &LongSubtractTemplate !!js/function >\n (arg) => {\n return `${arg} -`;\n }\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: &LongMultiplyTemplate !!js/function >\n (arg) => {\n return `${arg} *`;\n }\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: &LongDivTemplate !!js/function >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: &LongDivArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: &LongModuloTemplate !!js/function >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: &LongModuloArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: &LongAndTemplate !!js/function >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: &LongAndArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: &LongOrTemplate !!js/function >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: &LongOrArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: &LongXorTemplate !!js/function >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: &LongXorArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: &LongShiftLeftTemplate !!js/function >\n (lhs) => {\n return `${lhs} <<`;\n }\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftRightTemplate: &LongShiftRightTemplate !!js/function >\n (lhs) => {\n return `${lhs} >>`;\n }\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongCompareTemplate: &LongCompareTemplate !!js/function >\n (lhs) => {\n return `${lhs} -`;\n }\n LongCompareArgsTemplate: &LongCompareArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongIsOddTemplate: &LongIsOddTemplate !!js/function >\n (lhs) => {\n return `(${lhs} % 2) == 1`;\n }\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongIsZeroTemplate: &LongIsZeroTemplate !!js/function >\n (lhs) => {\n return `${lhs} == 0`;\n }\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongIsNegativeTemplate: &LongIsNegativeTemplate !!js/function >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate !!js/function >\n () => {\n return '';\n }\n LongNegateTemplate: &LongNegateTemplate !!js/function >\n () => {\n return '-';\n }\n LongNegateArgsTemplate: &LongNegateArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongNotTemplate: &LongNotTemplate !!js/function >\n () => {\n return '~';\n }\n LongNotArgsTemplate: &LongNotArgsTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n LongNotEqualsTemplate: &LongNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: &LongGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: &LongLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: &LongFloatApproxTemplate !!js/function >\n (lhs) => {\n return `${lhs}.to_f`;\n }\n LongTopTemplate: &LongTopTemplate !!js/function >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: &LongBottomTemplate !!js/function >\n (lhs) => {\n return `${lhs} & 0x0000ffff`;\n }\n TimestampToStringTemplate: &TimestampToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.to_s`;\n }\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate !!js/function >\n () => {\n return '';\n }\n TimestampEqualsTemplate: &TimestampEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} == `;\n }\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGetLowBitsTemplate: &TimestampGetLowBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.seconds`;\n }\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate !!js/function >\n () => {\n return ''\n }\n TimestampGetHighBitsTemplate: &TimestampGetHighBitsTemplate !!js/function >\n (lhs) => {\n return `${lhs}.increment`;\n }\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate !!js/function >\n () => {\n return ''\n }\n TimestampTTemplate: &TimestampTTemplate !!js/function >\n (lhs) => {\n return `${lhs}.seconds`;\n }\n TimestampITemplate: &TimestampITemplate !!js/function >\n (lhs) => {\n return `${lhs}.increment`;\n }\n TimestampAsDateTemplate: &TimestampAsDateTemplate !!js/function >\n (lhs) => {\n return `Time.at(${lhs}.increment).utc`;\n }\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate null\n TimestampCompareTemplate: &TimestampCompareTemplate !!js/function >\n (lhs) => {\n return `${lhs} <=> `;\n }\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate !!js/function >\n (lhs) => {\n return `${lhs} != `;\n }\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} > `;\n }\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} >= `;\n }\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanTemplate: &TimestampLessThanTemplate !!js/function >\n (lhs) => {\n return `${lhs} < `;\n }\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate !!js/function >\n (lhs) => {\n return `${lhs} <= `;\n }\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}`;\n }\n SymbolValueOfTemplate: &SymbolValueOfTemplate !!js/function >\n (lhs) => {\n return lhs;\n }\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate !!js/function >\n () => {\n return '';\n }\n SymbolInspectTemplate: &SymbolInspectTemplate !!js/function >\n (lhs) => {\n return `${lhs}.inspect`;\n }\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate !!js/function >\n () => {\n return '';\n }\n SymbolToStringTemplate: &SymbolToStringTemplate !!js/function >\n (lhs) => {\n let extractRegex = (lhs) => {\n let r = /^:'(.*)'$/;\n let arr = r.exec(lhs);\n return arr ? arr[1] : ''\n\n }\n let res = extractRegex(lhs)\n return res ? `'${res}'` : `${lhs}.to_s`;\n }\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate !!js/function >\n (lhs) => {\n return `${lhs}.to_s`;\n }\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate !!js/function >\n (lhs) => {\n return '';\n }\n\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These're variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don't overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate !!js/function >\n () => {\n return '9223372036854775807';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: &LongSymbolMinTemplate !!js/function >\n () => {\n return '-9223372036854775808';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate !!js/function >\n () => {\n return '0';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: &LongSymbolOneTemplate !!js/function >\n () => {\n return '1';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate !!js/function >\n () => {\n return '-1';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate !!js/function >\n (lhs, arg) => {\n return arg;\n }\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate null\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate !!js/function >\n () => {\n return '';\n }\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `${arg}.to_i`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate !!js/function >\n () => {\n return 'BSON::Decimal128';\n }\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `.new(${arg})`;\n }\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate !!js/function >\n () => {\n return 'BSON::ObjectId';\n }\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate !!js/function >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate !!js/function >\n () => {\n return 'BSON::ObjectId.from_time';\n }\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate !!js/function >\n (lhs, arg, isNumber) => {\n if (!isNumber) {\n return `(${arg})`;\n }\n return `(Time.at(${arg}))`;\n }\n # non bson-specific would go here, but there aren't any atm.\n\n #############################################\n # Imports #\n # #\n # Each type has a 'code' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: &ImportTemplate !!js/function >\n (args) => {\n let set = new Set(Object.values(args))\n if (set.has(`require 'mongo'`)) return `require 'mongo'`\n return [...set].sort().join('\\n');\n }\n DriverImportTemplate: &DriverImportTemplate !!js/function >\n () => {\n return `require 'mongo'`\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate null\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: &100ImportTemplate !!js/function >\n () => {\n return `require 'bson'`\n }\n 101ImportTemplate: &101ImportTemplate !!js/function >\n () => {\n return `require 'bson'`\n }\n 102ImportTemplate: &102ImportTemplate !!js/function >\n () => {\n return `require 'bson'`\n }\n 103ImportTemplate: &103ImportTemplate !!js/function >\n () => {\n return `require 'bson'`\n }\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n 107ImportTemplate: &107ImportTemplate !!js/function >\n () => {\n return `require 'bson'`\n }\n 108ImportTemplate: &108ImportTemplate !!js/function >\n () => {\n return `require 'bson'`\n }\n 109ImportTemplate: &109ImportTemplate null\n 110ImportTemplate: &110ImportTemplate !!js/function >\n () => {\n return `require 'bson'`\n }\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: &112ImportTemplate !!js/function >\n () => {\n return `require 'bson'`\n }\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate null\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; +module.exports = + "SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace 'null' with '!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: ''\n y: ''\n g: ''\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: ''\n l: ''\n u: ''\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: !!js/function &DriverTemplate >\n (spec) => {\n comment = '# Requires the MongoDB Ruby Driver\\n# https://docs.mongodb.com/ruby-driver/master/';\n\n const getKey = k => {\n let translateKey = {\n project: 'projection',\n maxTimeMS: 'max_time_ms'\n }\n return k in translateKey ? translateKey[k] : k\n };\n const options = spec.options;\n const filter = spec.filter || {}\n const exportMode = spec.exportMode;\n\n delete spec.options;\n delete spec.filter\n delete spec.exportMode;\n\n const connect = `client = Mongo::Client.new('${options.uri}', :database => '${options.database}')`;\n const coll = `client.database['${options.collection}']`;\n\n let driverMethod;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'delete_many';\n break;\n case 'Update Query':\n driverMethod = 'update_many';\n break;\n default:\n driverMethod = 'find';\n }\n\n if ('aggregation' in spec) {\n return `${comment}\\n\\n${connect}\\nresult = ${coll}.aggregate(${spec.aggregation})`;\n }\n\n const vars = Object.keys(spec).reduce(\n (result, k) => {\n return `${result}\\n${getKey(k)} = ${spec[k]}`;\n },\n connect\n );\n\n const args = Object.keys(spec).reduce(\n (result, k) => {\n const divider = result === '' ? '' : ',\\n';\n return `${result}${divider} ${getKey(k)}: ${getKey(k)}`;\n },\n ''\n );\n\n const cmd = `result = ${coll}.${driverMethod}(${filter}${args ? `, {\\n${args}\\n}` : ''})`;\n\n return `${comment}\\n\\n${vars}\\n\\n${cmd}`;\n }\n EqualitySyntaxTemplate: !!js/function &EqualitySyntaxTemplate >\n (lhs, op, rhs) => {\n if (op.includes('is')) {\n let not = op.includes('not') ? '!' : ''\n return `${not}${lhs}.equal?(${rhs})`\n } else if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n } else if (op === '==' || op === '===') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: !!js/function &InSyntaxTemplate >\n (lhs, op, rhs) => {\n let str = '';\n if (op.includes('!') || op.includes('not')) {\n str = '!';\n }\n return `${str}${rhs}.include?(${lhs})`\n }\n AndSyntaxTemplate: !!js/function &AndSyntaxTemplate >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: !!js/function &OrSyntaxTemplate >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: !!js/function &NotSyntaxTemplate >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate null\n BinarySyntaxTemplate: !!js/function &BinarySyntaxTemplate >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `${s}.div(${rhs})`;\n case '**':\n return `${s} ** ${rhs}`;\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosTemplate: &EosSyntaxTemplate null # No args. End-of-line\n EofTemplate: &EofSyntaxTemplate null # No args. End-of-file\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: !!js/function &StringTypeTemplate >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n RegexTypeTemplate: !!js/function &RegexTypeTemplate >\n (pattern, flags) => {\n const str = pattern;\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n pattern = `${newStr.replace(/\\\\([\\s\\S])/g, '\\\\$1')}`;\n return `/${pattern}/${flags ? flags : ''}`;\n }\n BoolTypeTemplate: !!js/function &BoolTypeTemplate >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null # args: literal, argType (i.e. '_string', '_decimal' etc)\n DecimalTypeTemplate: &DecimalTypeTemplate null # args: literal, argType\n LongBasicTypeTemplate: &LongBasicTypeTemplate null # args: literal, argType\n HexTypeTemplate: &HexTypeTemplate null # args: literal, argType\n OctalTypeTemplate: !!js/function &OctalTypeTemplate >\n (literal) => {\n let offset = 0;\n\n if (\n literal.charAt(0) === '0' &&\n (literal.charAt(1) === '0' || literal.charAt(1) === 'o' || literal.charAt(1) === 'O')\n ) {\n offset = 2;\n } else if (literal.charAt(0) === '0') {\n offset = 1;\n }\n\n literal = `0o${literal.substr(offset, literal.length - 1)}`;\n\n return literal;\n }\n NumericTypeTemplate: &NumericTypeTemplate null # args: literal, argType\n ArrayTypeTemplate: !!js/function &ArrayTypeTemplate >\n (literal, depth) => {\n depth++;\n if (literal === '') {\n return '[]'\n }\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n\n return `[${indent}${literal}${closingIndent}]`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate null # Args: single array element, nestedness, lastElement? (note: not being used atm)\n NullTypeTemplate: !!js/function &NullTypeTemplate >\n () => {\n return 'nil';\n }\n UndefinedTypeTemplate: !!js/function &UndefinedTypeTemplate >\n () => {\n return 'nil';\n }\n ObjectTypeTemplate: !!js/function &ObjectTypeTemplate >\n (literal) => {\n if (literal === '') {\n return '{}';\n }\n return literal;\n }\n ObjectTypeArgsTemplate: !!js/function &ObjectTypeArgsTemplate >\n (args, depth) => {\n if (args.length === 0) {\n return '{}';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n const pairs = args.map((arg) => {\n return `${indent}${singleStringify(arg[0])} => ${arg[1]}`;\n }).join(',');\n\n return `{${pairs}${closingIndent}}`\n }\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don't take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: !!js/function &CodeSymbolTemplate >\n () => {\n return 'BSON::Code'\n }\n CodeSymbolArgsTemplate: !!js/function &CodeSymbolArgsTemplate >\n (lhs, code, scope) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n if (code === undefined) {\n return '.new'\n }\n return !scope ? `.new(${singleStringify(code)})` : `WithScope.new(${singleStringify(code)}, ${scope})`\n }\n ObjectIdSymbolTemplate: !!js/function &ObjectIdSymbolTemplate >\n () => {\n return 'BSON::ObjectId';\n }\n ObjectIdSymbolArgsTemplate: !!js/function &ObjectIdSymbolArgsTemplate >\n (lhs, id) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n return !id ? '.new' : `(${singleStringify(id)})`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate null\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate null\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate null\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate null\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate null\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate null\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template null\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate null\n DBRefSymbolTemplate: !!js/function &DBRefSymbolTemplate >\n () => {\n return 'BSON::DBRef'\n }\n DBRefSymbolArgsTemplate: !!js/function &DBRefSymbolArgsTemplate >\n (lhs, coll, id, db) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `'${newStr.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2')}'`;\n }\n\n let db_string = db ? `,\\n '$db' => ${singleStringify(db)}` : ''\n return `.new(\\n '$ref' => ${singleStringify(coll)},\\n '$id' => ${id}${db_string}\\n)`\n }\n DoubleSymbolTemplate: !!js/function &DoubleSymbolTemplate >\n () => {\n return '';\n }\n DoubleSymbolArgsTemplate: !!js/function &DoubleSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_decimal' || type === '_double') {\n return arg;\n }\n return `${arg}.to_f`;\n }\n Int32SymbolTemplate: !!js/function &Int32SymbolTemplate >\n () => {\n return '';\n }\n Int32SymbolArgsTemplate: !!js/function &Int32SymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long') {\n return arg;\n }\n return `${arg}.to_i`;\n }\n LongSymbolTemplate: !!js/function &LongSymbolTemplate >\n () => {\n return ''\n }\n LongSymbolArgsTemplate: !!js/function &LongSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long') {\n return arg;\n }\n return `${arg}.to_i`;\n }\n RegExpSymbolTemplate: !!js/function &RegExpSymbolTemplate >\n () => {\n return '';\n }\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: !!js/function &SymbolSymbolTemplate >\n () => {\n return '';\n }\n SymbolSymbolArgsTemplate: !!js/function &SymbolSymbolArgsTemplate >\n (lhs, arg) => {\n arg = arg === undefined ? '' : arg;\n const str = arg.toString();\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n return `:'${newStr}'`;\n } else {\n return `${newStr}.to_sym`;\n }\n }\n BSONRegExpSymbolTemplate: !!js/function &BSONRegExpSymbolTemplate >\n () => {\n return '';\n }\n BSONRegExpSymbolArgsTemplate: !!js/function &BSONRegExpSymbolArgsTemplate >\n (lhs, pattern, flags) => {\n const singleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `${newStr.replace(/\\\\([\\s\\S])/g, '\\\\$1')}`;\n }\n return `/${singleStringify(pattern)}/${flags ? singleStringify(flags) : ''}`;\n }\n Decimal128SymbolTemplate: !!js/function &Decimal128SymbolTemplate >\n () => {\n return 'BSON::Decimal128';\n }\n Decimal128SymbolArgsTemplate: !!js/function &Decimal128SymbolArgsTemplate >\n (lhs, arg) => {\n arg = arg === undefined ? '0' : arg.toString();\n if (arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'') {\n return `.new(${arg})`;\n }\n return `.new('${arg}')`;\n }\n MinKeySymbolTemplate: !!js/function &MinKeySymbolTemplate >\n () => {\n return 'BSON::MinKey';\n }\n MinKeySymbolArgsTemplate: !!js/function &MinKeySymbolArgsTemplate >\n () => {\n return '.new';\n }\n MaxKeySymbolTemplate: !!js/function &MaxKeySymbolTemplate >\n () => {\n return 'BSON::MaxKey';\n }\n MaxKeySymbolArgsTemplate: !!js/function &MaxKeySymbolArgsTemplate >\n () => {\n return '.new';\n }\n TimestampSymbolTemplate: !!js/function &TimestampSymbolTemplate >\n () => {\n return 'BSON::Timestamp';\n }\n TimestampSymbolArgsTemplate: !!js/function &TimestampSymbolArgsTemplate >\n (lhs, arg1, arg2) => {\n return `.new(${arg1 === undefined ? 0 : arg1}, ${arg2 === undefined ? 0 : arg2})`;\n }\n # non bson-specific\n NumberSymbolTemplate: !!js/function &NumberSymbolTemplate >\n () => {\n return '';\n }\n NumberSymbolArgsTemplate: !!js/function &NumberSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n const str = arg.toString();\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n return `'${newStr}'.to_f`;\n } else if (type === '_decimal' || type === '_double') {\n return newStr;\n } else {\n return `${newStr}.to_f`;\n }\n }\n DateSymbolTemplate: !!js/function &DateSymbolTemplate >\n () => {\n return 'Time';\n }\n DateSymbolArgsTemplate: !!js/function &DateSymbolArgsTemplate >\n (lhs, date, isString) => {\n const toStr = isString ? '.strftime(\\'%a %b %d %Y %H:%M:%S %Z\\')' : '';\n\n if (date === null) {\n return `${lhs}.new.utc${toStr}`;\n }\n\n const dateStr = [\n date.getUTCFullYear(),\n date.getUTCMonth() + 1,\n date.getUTCDate(),\n date.getUTCHours(),\n date.getUTCMinutes(),\n date.getUTCSeconds()\n ].join(', ');\n\n return `${lhs}.utc(${dateStr})${toStr}`;\n }\n\n DateSymbolNowTemplate: !!js/function &DateSymbolNowTemplate >\n () => {\n return 'Time.now.utc';\n }\n DateSymbolNowArgsTemplate: !!js/function &DateSymbolNowArgsTemplate >\n (args) => {\n return '';\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These're variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: !!js/function &CodeCodeTemplate >\n (lhs) => {\n return `${lhs}.javascript`;\n }\n CodeCodeArgsTemplate: !!js/function &CodeCodeArgsTemplate >\n () => {\n return '';\n }\n CodeScopeTemplate: !!js/function &CodeScopeTemplate >\n (lhs) => {\n return `${lhs}.scope`;\n }\n CodeScopeArgsTemplate: !!js/function &CodeScopeArgsTemplate >\n () => {\n return '';\n }\n ObjectIdToStringTemplate: !!js/function &ObjectIdToStringTemplate >\n (lhs) => {\n return `${lhs}.to_s`;\n }\n ObjectIdToStringArgsTemplate: !!js/function &ObjectIdToStringArgsTemplate >\n () => {\n return '';\n }\n ObjectIdEqualsTemplate: !!js/function &ObjectIdEqualsTemplate >\n (lhs) => {\n return `${lhs} == `;\n }\n ObjectIdEqualsArgsTemplate: !!js/function &ObjectIdEqualsArgsTemplate >\n (arg) => {\n return `${arg}`;\n }\n ObjectIdGetTimestampTemplate: !!js/function &ObjectIdGetTimestampTemplate >\n (lhs) => {\n return `${lhs}.to_time`;\n }\n ObjectIdGetTimestampArgsTemplate:\n !!js/function &ObjectIdGetTimestampArgsTemplate >\n () => {\n return '';\n }\n ObjectIdIsValidTemplate: !!js/function &ObjectIdIsValidTemplate >\n (lhs) => {\n return `${lhs}.legal?`\n }\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate null\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate null\n BinaryLengthTemplate: &BinaryLengthTemplate null\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate null\n BinaryToStringTemplate: &BinaryToStringTemplate null\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate null\n BinarySubtypeTemplate: &BinarySubtypeTemplate null\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate null\n DBRefGetDBTemplate: !!js/function &DBRefGetDBTemplate >\n (lhs) => {\n return `${lhs}.database`;\n }\n DBRefGetCollectionTemplate: !!js/function &DBRefGetCollectionTemplate >\n (lhs) => {\n return `${lhs}.collection`;\n }\n DBRefGetIdTemplate: !!js/function &DBRefGetIdTemplate >\n (lhs) => {\n return `${lhs}.id`;\n }\n DBRefGetDBArgsTemplate: !!js/function &DBRefGetDBArgsTemplate >\n (lhs) => {\n return '';\n }\n DBRefGetCollectionArgsTemplate:\n !!js/function &DBRefGetCollectionArgsTemplate >\n (lhs) => {\n return '';\n }\n DBRefGetIdArgsTemplate: !!js/function &DBRefGetIdArgsTemplate >\n (lhs) => {\n return '';\n }\n DBRefToStringTemplate: !!js/function &DBRefToStringTemplate >\n (lhs) => {\n return '${lhs}.to_s';\n }\n DBRefToStringArgsTemplate: !!js/function &DBRefToStringArgsTemplate >\n () => {\n return '';\n }\n DoubleValueOfTemplate: &DoubleValueOfTemplate null\n DoubleValueOfArgsTemplate: &DoubleValueOfArgsTemplate null\n Int32ValueOfTemplate: &Int32ValueOfTemplate null\n Int32ValueOfArgsTemplate: &Int32ValueOfArgsTemplate null\n Int32ToStringTemplate: &Int32ToStringTemplate null\n Int32ToStringArgsTemplate: &Int32ToStringArgsTemplate null\n LongEqualsTemplate: !!js/function &LongEqualsTemplate >\n (lhs) => {\n return `${lhs} ==`;\n }\n LongEqualsArgsTemplate: !!js/function &LongEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongToIntTemplate: !!js/function &LongToIntTemplate >\n (lhs) => {\n return `${lhs}`;\n }\n LongToIntArgsTemplate: !!js/function &LongToIntArgsTemplate >\n () => {\n return '';\n }\n LongToStringTemplate: !!js/function &LongToStringTemplate >\n (lhs) => {\n return `${lhs}.to_s`;\n }\n LongToStringArgsTemplate: !!js/function &LongToStringArgsTemplate >\n () => {\n return '';\n }\n LongToNumberTemplate: !!js/function &LongToNumberTemplate >\n (lhs) => {\n return `${lhs}.to_f`;\n }\n LongToNumberArgsTemplate: !!js/function &LongToNumberArgsTemplate >\n () => {\n return '';\n }\n LongAddTemplate: !!js/function &LongAddTemplate >\n (lhs) => {\n return `${lhs} +`;\n }\n LongAddArgsTemplate: !!js/function &LongAddArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongSubtractTemplate: !!js/function &LongSubtractTemplate >\n (arg) => {\n return `${arg} -`;\n }\n LongSubtractArgsTemplate: !!js/function &LongSubtractArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongMultiplyTemplate: !!js/function &LongMultiplyTemplate >\n (arg) => {\n return `${arg} *`;\n }\n LongMultiplyArgsTemplate: !!js/function &LongMultiplyArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongDivTemplate: !!js/function &LongDivTemplate >\n (lhs) => {\n return `${lhs} /`;\n }\n LongDivArgsTemplate: !!js/function &LongDivArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongModuloTemplate: !!js/function &LongModuloTemplate >\n (lhs) => {\n return `${lhs} %`;\n }\n LongModuloArgsTemplate: !!js/function &LongModuloArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongAndTemplate: !!js/function &LongAndTemplate >\n (lhs) => {\n return `${lhs} &`;\n }\n LongAndArgsTemplate: !!js/function &LongAndArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongOrTemplate: !!js/function &LongOrTemplate >\n (lhs) => {\n return `${lhs} |`;\n }\n LongOrArgsTemplate: !!js/function &LongOrArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongXorTemplate: !!js/function &LongXorTemplate >\n (lhs) => {\n return `${lhs} ^`;\n }\n LongXorArgsTemplate: !!js/function &LongXorArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftLeftTemplate: !!js/function &LongShiftLeftTemplate >\n (lhs) => {\n return `${lhs} <<`;\n }\n LongShiftLeftArgsTemplate: !!js/function &LongShiftLeftArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongShiftRightTemplate: !!js/function &LongShiftRightTemplate >\n (lhs) => {\n return `${lhs} >>`;\n }\n LongShiftRightArgsTemplate: !!js/function &LongShiftRightArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongCompareTemplate: !!js/function &LongCompareTemplate >\n (lhs) => {\n return `${lhs} -`;\n }\n LongCompareArgsTemplate: !!js/function &LongCompareArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongIsOddTemplate: !!js/function &LongIsOddTemplate >\n (lhs) => {\n return `(${lhs} % 2) == 1`;\n }\n LongIsOddArgsTemplate: !!js/function &LongIsOddArgsTemplate >\n () => {\n return '';\n }\n LongIsZeroTemplate: !!js/function &LongIsZeroTemplate >\n (lhs) => {\n return `${lhs} == 0`;\n }\n LongIsZeroArgsTemplate: !!js/function &LongIsZeroArgsTemplate >\n () => {\n return '';\n }\n LongIsNegativeTemplate: !!js/function &LongIsNegativeTemplate >\n (lhs) => {\n return `${lhs} < 0`;\n }\n LongIsNegativeArgsTemplate: !!js/function &LongIsNegativeArgsTemplate >\n () => {\n return '';\n }\n LongNegateTemplate: !!js/function &LongNegateTemplate >\n () => {\n return '-';\n }\n LongNegateArgsTemplate: !!js/function &LongNegateArgsTemplate >\n (lhs) => {\n return lhs;\n }\n LongNotTemplate: !!js/function &LongNotTemplate >\n () => {\n return '~';\n }\n LongNotArgsTemplate: !!js/function &LongNotArgsTemplate >\n (lhs) => {\n return lhs;\n }\n LongNotEqualsTemplate: !!js/function &LongNotEqualsTemplate >\n (lhs) => {\n return `${lhs} !=`;\n }\n LongNotEqualsArgsTemplate: !!js/function &LongNotEqualsArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanTemplate: !!js/function &LongGreaterThanTemplate >\n (lhs) => {\n return `${lhs} >`;\n }\n LongGreaterThanArgsTemplate: !!js/function &LongGreaterThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongGreaterThanOrEqualTemplate:\n !!js/function &LongGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} >=`;\n }\n LongGreaterThanOrEqualArgsTemplate:\n !!js/function &LongGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanTemplate: !!js/function &LongLessThanTemplate >\n (lhs) => {\n return `${lhs} <`;\n }\n LongLessThanArgsTemplate: !!js/function &LongLessThanArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongLessThanOrEqualTemplate: !!js/function &LongLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} <=`;\n }\n LongLessThanOrEqualArgsTemplate:\n !!js/function &LongLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return ` ${arg}`;\n }\n LongFloatApproxTemplate: !!js/function &LongFloatApproxTemplate >\n (lhs) => {\n return `${lhs}.to_f`;\n }\n LongTopTemplate: !!js/function &LongTopTemplate >\n (lhs) => {\n return `${lhs} >> 32`;\n }\n LongBottomTemplate: !!js/function &LongBottomTemplate >\n (lhs) => {\n return `${lhs} & 0x0000ffff`;\n }\n TimestampToStringTemplate: !!js/function &TimestampToStringTemplate >\n (lhs) => {\n return `${lhs}.to_s`;\n }\n TimestampToStringArgsTemplate: !!js/function &TimestampToStringArgsTemplate >\n () => {\n return '';\n }\n TimestampEqualsTemplate: !!js/function &TimestampEqualsTemplate >\n (lhs) => {\n return `${lhs} == `;\n }\n TimestampEqualsArgsTemplate: !!js/function &TimestampEqualsArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGetLowBitsTemplate: !!js/function &TimestampGetLowBitsTemplate >\n (lhs) => {\n return `${lhs}.seconds`;\n }\n TimestampGetLowBitsArgsTemplate:\n !!js/function &TimestampGetLowBitsArgsTemplate >\n () => {\n return ''\n }\n TimestampGetHighBitsTemplate: !!js/function &TimestampGetHighBitsTemplate >\n (lhs) => {\n return `${lhs}.increment`;\n }\n TimestampGetHighBitsArgsTemplate:\n !!js/function &TimestampGetHighBitsArgsTemplate >\n () => {\n return ''\n }\n TimestampTTemplate: !!js/function &TimestampTTemplate >\n (lhs) => {\n return `${lhs}.seconds`;\n }\n TimestampITemplate: !!js/function &TimestampITemplate >\n (lhs) => {\n return `${lhs}.increment`;\n }\n TimestampAsDateTemplate: !!js/function &TimestampAsDateTemplate >\n (lhs) => {\n return `Time.at(${lhs}.increment).utc`;\n }\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate null\n TimestampCompareTemplate: !!js/function &TimestampCompareTemplate >\n (lhs) => {\n return `${lhs} <=> `;\n }\n TimestampCompareArgsTemplate: !!js/function &TimestampCompareArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampNotEqualsTemplate: !!js/function &TimestampNotEqualsTemplate >\n (lhs) => {\n return `${lhs} != `;\n }\n TimestampNotEqualsArgsTemplate:\n !!js/function &TimestampNotEqualsArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanTemplate: !!js/function &TimestampGreaterThanTemplate >\n (lhs) => {\n return `${lhs} > `;\n }\n TimestampGreaterThanArgsTemplate:\n !!js/function &TimestampGreaterThanArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampGreaterThanOrEqualTemplate:\n !!js/function &TimestampGreaterThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} >= `;\n }\n TimestampGreaterThanOrEqualArgsTemplate:\n !!js/function &TimestampGreaterThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanTemplate: !!js/function &TimestampLessThanTemplate >\n (lhs) => {\n return `${lhs} < `;\n }\n TimestampLessThanArgsTemplate: !!js/function &TimestampLessThanArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n TimestampLessThanOrEqualTemplate:\n !!js/function &TimestampLessThanOrEqualTemplate >\n (lhs) => {\n return `${lhs} <= `;\n }\n TimestampLessThanOrEqualArgsTemplate:\n !!js/function &TimestampLessThanOrEqualArgsTemplate >\n (lhs, arg) => {\n return `${arg}`;\n }\n SymbolValueOfTemplate: !!js/function &SymbolValueOfTemplate >\n (lhs) => {\n return lhs;\n }\n SymbolValueOfArgsTemplate: !!js/function &SymbolValueOfArgsTemplate >\n () => {\n return '';\n }\n SymbolInspectTemplate: !!js/function &SymbolInspectTemplate >\n (lhs) => {\n return `${lhs}.inspect`;\n }\n SymbolInspectArgsTemplate: !!js/function &SymbolInspectArgsTemplate >\n () => {\n return '';\n }\n SymbolToStringTemplate: !!js/function &SymbolToStringTemplate >\n (lhs) => {\n let extractRegex = (lhs) => {\n let r = /^:'(.*)'$/;\n let arr = r.exec(lhs);\n return arr ? arr[1] : ''\n\n }\n let res = extractRegex(lhs)\n return res ? `'${res}'` : `${lhs}.to_s`;\n }\n SymbolToStringArgsTemplate: !!js/function &SymbolToStringArgsTemplate >\n (lhs) => {\n return '';\n }\n Decimal128ToStringTemplate: !!js/function &Decimal128ToStringTemplate >\n (lhs) => {\n return `${lhs}.to_s`;\n }\n Decimal128ToStringArgsTemplate:\n !!js/function &Decimal128ToStringArgsTemplate >\n (lhs) => {\n return '';\n }\n\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These're variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don't overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: !!js/function &LongSymbolMaxTemplate >\n () => {\n return '9223372036854775807';\n }\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate null\n LongSymbolMinTemplate: !!js/function &LongSymbolMinTemplate >\n () => {\n return '-9223372036854775808';\n }\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate null\n LongSymbolZeroTemplate: !!js/function &LongSymbolZeroTemplate >\n () => {\n return '0';\n }\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate null\n LongSymbolOneTemplate: !!js/function &LongSymbolOneTemplate >\n () => {\n return '1';\n }\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate null\n LongSymbolNegOneTemplate: !!js/function &LongSymbolNegOneTemplate >\n () => {\n return '-1';\n }\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate null\n LongSymbolFromBitsTemplate: !!js/function &LongSymbolFromBitsTemplate >\n () => {\n return '';\n }\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate null\n LongSymbolFromIntTemplate: !!js/function &LongSymbolFromIntTemplate >\n () => {\n return '';\n }\n LongSymbolFromIntArgsTemplate: !!js/function &LongSymbolFromIntArgsTemplate >\n (lhs, arg) => {\n return arg;\n }\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate null\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate null\n LongSymbolFromStringTemplate: !!js/function &LongSymbolFromStringTemplate >\n () => {\n return '';\n }\n LongSymbolFromStringArgsTemplate:\n !!js/function &LongSymbolFromStringArgsTemplate >\n (lhs, arg) => {\n return `${arg}.to_i`;\n }\n Decimal128SymbolFromStringTemplate:\n !!js/function &Decimal128SymbolFromStringTemplate >\n () => {\n return 'BSON::Decimal128';\n }\n Decimal128SymbolFromStringArgsTemplate:\n !!js/function &Decimal128SymbolFromStringArgsTemplate >\n (lhs, arg) => {\n return `.new(${arg})`;\n }\n ObjectIdCreateFromHexStringTemplate:\n !!js/function &ObjectIdCreateFromHexStringTemplate >\n () => {\n return 'BSON::ObjectId';\n }\n ObjectIdCreateFromHexStringArgsTemplate:\n !!js/function &ObjectIdCreateFromHexStringArgsTemplate >\n (lhs, arg) => {\n return `(${arg})`;\n }\n ObjectIdCreateFromTimeTemplate:\n !!js/function &ObjectIdCreateFromTimeTemplate >\n () => {\n return 'BSON::ObjectId.from_time';\n }\n ObjectIdCreateFromTimeArgsTemplate:\n !!js/function &ObjectIdCreateFromTimeArgsTemplate >\n (lhs, arg, isNumber) => {\n if (!isNumber) {\n return `(${arg})`;\n }\n return `(Time.at(${arg}))`;\n }\n # non bson-specific would go here, but there aren't any atm.\n #############################################\n # Imports #\n # #\n # Each type has a 'code' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: !!js/function &ImportTemplate >\n (args) => {\n let set = new Set(Object.values(args))\n if (set.has(`require 'mongo'`)) return `require 'mongo'`\n return [...set].sort().join('\\n');\n }\n DriverImportTemplate: !!js/function &DriverImportTemplate >\n () => {\n return `require 'mongo'`\n }\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate null\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate null\n 11ImportTemplate: &11ImportTemplate null\n 12ImportTemplate: &12ImportTemplate null\n 100ImportTemplate: !!js/function &100ImportTemplate >\n () => {\n return `require 'bson'`\n }\n 101ImportTemplate: !!js/function &101ImportTemplate >\n () => {\n return `require 'bson'`\n }\n 102ImportTemplate: !!js/function &102ImportTemplate >\n () => {\n return `require 'bson'`\n }\n 103ImportTemplate: !!js/function &103ImportTemplate >\n () => {\n return `require 'bson'`\n }\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n 107ImportTemplate: !!js/function &107ImportTemplate >\n () => {\n return `require 'bson'`\n }\n 108ImportTemplate: !!js/function &108ImportTemplate >\n () => {\n return `require 'bson'`\n }\n 109ImportTemplate: &109ImportTemplate null\n 110ImportTemplate: !!js/function &110ImportTemplate >\n () => {\n return `require 'bson'`\n }\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: !!js/function &112ImportTemplate >\n () => {\n return `require 'bson'`\n }\n 113ImportTemplate: &113ImportTemplate null\n 114ImportTemplate: &114ImportTemplate null\n 200ImportTemplate: &200ImportTemplate null\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; diff --git a/packages/bson-transpilers/lib/symbol-table/shelltorust.js b/packages/bson-transpilers/lib/symbol-table/shelltorust.js index 5e79f5cfb24..1d172555e63 100644 --- a/packages/bson-transpilers/lib/symbol-table/shelltorust.js +++ b/packages/bson-transpilers/lib/symbol-table/shelltorust.js @@ -1 +1,2 @@ -module.exports="SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace 'null' with '!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'u'\n y: ''\n g: ''\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: &DriverTemplate !!js/function >\n (spec) => {\n const comment = `// Requires the MongoDB crate.\\n// https://crates.io/crates/mongodb`;\n \n const options = spec.options;\n const filter = spec.filter || 'None';\n const exportMode = spec.exportMode;\n delete spec.options;\n delete spec.filter;\n delete spec.exportMode;\n\n const connect = `let client = Client::with_uri_str(\"${options.uri}\").await?;`\n const coll = `client.database(\"${options.database}\").collection::(\"${options.collection}\")`;\n\n if ('aggregation' in spec) {\n let agg = spec.aggregation;\n if (agg.charAt(0) != '[') {\n agg = `[${agg}]`;\n }\n return `${comment}\\n\\n${connect}\\nlet result = ${coll}.aggregate(${agg}, None).await?;`;\n }\n\n let driverMethod;\n let optionsName;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'delete_many';\n optionsName = 'DeleteOptions';\n break;\n case 'Update Query':\n driverMethod = 'update_many';\n optionsName = 'UpdateOptions';\n break;\n default:\n driverMethod = 'find';\n optionsName = 'FindOptions';\n break;\n }\n\n const findOpts = [];\n for (const k in spec) {\n let optName = k;\n let optValue = spec[k];\n switch(k) {\n case 'project':\n optName = 'projection';\n break;\n case 'maxTimeMS':\n optName = 'max_time';\n optValue = `std::time::Duration::from_millis(${optValue})`;\n break;\n }\n findOpts.push(` .${optName}(${optValue})`);\n }\n let optStr = '';\n if (findOpts.length > 0) {\n optStr = `let options = mongodb::options::${optionsName}::builder()\\n${findOpts.join('\\n')}\\n .build();\\n`;\n }\n let optRef = optStr ? 'options' : 'None';\n const cmd = `let result = ${coll}.${driverMethod}(${filter}, ${optRef}).await?;`;\n\n return `${comment}\\n\\n${connect}\\n${optStr}${cmd}`;\n }\n EqualitySyntaxTemplate: &EqualitySyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n }\n else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: &InSyntaxTemplate !!js/function >\n (lhs, op, rhs) => {\n let prefix = '';\n if (op.includes('!') || op.includes('not')) {\n prefix = '!';\n }\n return `${prefix}${rhs}.contains(&${lhs})`\n }\n AndSyntaxTemplate: &AndSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: &OrSyntaxTemplate !!js/function >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: &NotSyntaxTemplate !!js/function >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: &UnarySyntaxTemplate !!js/function >\n (op, val) => {\n switch(op) {\n case '+':\n return val;\n case '~':\n return `!${val}`;\n default:\n return `${op}${val}`;\n }\n return `${op}${val}`;\n }\n BinarySyntaxTemplate: &BinarySyntaxTemplate !!js/function >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `${s} / ${rhs}`\n case '**':\n return `${s}.pow(${rhs})`\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosTemplate: &EosSyntaxTemplate null # No args. End-of-line\n EofTemplate: &EofSyntaxTemplate null # No args. End-of-file\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: &StringTypeTemplate !!js/function >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n RegexTypeTemplate: &RegexTypeTemplate !!js/function >\n (pattern, flags) => {\n // Double-quote stringify\n let newPat = pattern;\n if (\n (pattern.charAt(0) === '\\'' && pattern.charAt(pattern.length - 1) === '\\'') ||\n (pattern.charAt(0) === '\"' && pattern.charAt(pattern.length - 1) === '\"')) {\n newPat = pattern.substr(1, pattern.length - 2);\n }\n return `Regex { pattern: \"${newPat.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\".to_string(), options: \"${flags}\".to_string() }`;\n }\n BoolTypeTemplate: &BoolTypeTemplate !!js/function >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null # args: literal, argType (i.e. '_string', '_decimal' etc)\n DecimalTypeTemplate: &DecimalTypeTemplate null # args: literal, argType\n LongBasicTypeTemplate: &LongBasicTypeTemplate null\n HexTypeTemplate: &HexTypeTemplate !!js/function >\n (literal, type) => {\n if (literal.charAt(1) === 'X') {\n return literal.charAt(0) + 'x' + literal.substring(2);\n }\n return literal;\n }\n OctalTypeTemplate: &OctalTypeTemplate !!js/function >\n (literal, type) => {\n switch(literal.charAt(1)) {\n case 'o':\n return literal;\n case 'O':\n case '0':\n return literal.charAt(0) + 'o' + literal.substring(2);\n default:\n return literal.charAt(0) + 'o' + literal.substring(1);\n }\n }\n NumericTypeTemplate: &NumericTypeTemplate null # args: literal, argType\n ArrayTypeTemplate: &ArrayTypeTemplate !!js/function >\n (literal, depth) => {\n if (literal === '') {\n return '[]'\n }\n return `[${literal}]`;\n }\n ArrayTypeArgsTemplate: &ArrayTypeArgsTemplate !!js/function >\n (element, depth, isLast) => {\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = isLast ? '\\n' + ' '.repeat(depth - 1) : ',';\n return `${indent}${element}${closingIndent}`;\n }\n NullTypeTemplate: &NullTypeTemplate !!js/function >\n () => 'Bson::Null'\n UndefinedTypeTemplate: &UndefinedTypeTemplate !!js/function >\n () => 'Bson::Undefined'\n ObjectTypeTemplate: &ObjectTypeTemplate !!js/function >\n (literal) => `doc! {${literal}}`\n ObjectTypeArgsTemplate: &ObjectTypeArgsTemplate !!js/function >\n (args, depth) => {\n if (args.length === 0) {\n return '';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n\n const pairs = args.map((pair) => {\n return `${indent}${doubleStringify(pair[0])}: ${pair[1]}`;\n }).join(',');\n\n return `${pairs}${closingIndent}`;\n\n }\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don't take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: &CodeSymbolTemplate !!js/function >\n () => ''\n CodeSymbolArgsTemplate: &CodeSymbolArgsTemplate !!js/function >\n (lhs, code, scope) => {\n // Double quote stringify\n let newStr = code === undefined ? '' : code;\n const str = newStr;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n code = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\".to_string()`;\n if (scope === undefined) {\n return `Bson::JavaScriptCode(${code})`;\n } else {\n return `JavaScriptCodeWithScope { code: ${code}, scope: ${scope} }`;\n }\n }\n ObjectIdSymbolTemplate: &ObjectIdSymbolTemplate !!js/function >\n () => 'ObjectId'\n ObjectIdSymbolArgsTemplate: &ObjectIdSymbolArgsTemplate !!js/function >\n (lhs, arg) => {\n if (arg === undefined || arg === '') {\n return '::new()';\n }\n // Double quote stringify\n let newArg = arg;\n if (\n (arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'') ||\n (arg.charAt(0) === '\"' && arg.charAt(arg.length - 1) === '\"')) {\n newArg = arg.substr(1, arg.length - 2);\n }\n newArg = `\"${newArg.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n return `::parse_str(${newArg})?`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate null\n BinarySymbolSubtypeDefaultTemplate: &BinarySymbolSubtypeDefaultTemplate !!js/function >\n () => 'BinarySubtype::Generic'\n BinarySymbolSubtypeFunctionTemplate: &BinarySymbolSubtypeFunctionTemplate !!js/function >\n () => 'BinarySubtype::Function'\n BinarySymbolSubtypeByteArrayTemplate: &BinarySymbolSubtypeByteArrayTemplate !!js/function >\n () => 'BinarySubtype::BinaryOld'\n BinarySymbolSubtypeUuidOldTemplate: &BinarySymbolSubtypeUuidOldTemplate !!js/function >\n () => 'BinarySubtype::UuidOld'\n BinarySymbolSubtypeUuidTemplate: &BinarySymbolSubtypeUuidTemplate !!js/function >\n () => 'BinarySubtype::Uuid'\n BinarySymbolSubtypeMd5Template: &BinarySymbolSubtypeMd5Template !!js/function >\n () => 'BinarySubtype::Md5'\n BinarySymbolSubtypeUserDefinedTemplate: &BinarySymbolSubtypeUserDefinedTemplate !!js/function >\n (arg) => `BinarySubtype::UserDefined(${arg})`\n DBRefSymbolTemplate: &DBRefSymbolTemplate null # No args\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null # Args: lhs, coll, id, db\n DoubleSymbolTemplate: &DoubleSymbolTemplate !!js/function >\n () => ''\n DoubleSymbolArgsTemplate: &DoubleSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_decimal' || type === '_double') {\n return arg;\n }\n if (type === '_integer' || type === '_long') {\n return `${arg}.0`;\n }\n if (type === '_string') {\n return `${arg}.parse::()?`;\n }\n return `f32::try_from(${arg})?`;\n }\n Int32SymbolTemplate: &Int32SymbolTemplate !!js/function >\n () => ''\n Int32SymbolArgsTemplate: &Int32SymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long' || type === '_hex' || type === '_octal') {\n return arg;\n }\n if (type === '_string') {\n return `${arg}.parse::()?`;\n }\n return `i32::try_from(${arg})?`;\n }\n LongSymbolTemplate: &LongSymbolTemplate !!js/function >\n () => ''\n LongSymbolArgsTemplate: &LongSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long' || type === '_hex' || type === '_octal') {\n return `${arg}i64`;\n }\n if (type === '_string') {\n return `${arg}.parse::()?`;\n }\n return `i64::try_from(${arg})?`;\n }\n RegExpSymbolTemplate: &RegExpSymbolTemplate !!js/function >\n () => 'Regex'\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: &SymbolSymbolTemplate !!js/function >\n () => 'Bson::Symbol'\n SymbolSymbolArgsTemplate: &SymbolSymbolArgsTemplate !!js/function >\n (_, arg) => `(${arg})`\n BSONRegExpSymbolTemplate: &BSONRegExpSymbolTemplate !!js/function >\n () => 'Regex'\n BSONRegExpSymbolArgsTemplate: &BSONRegExpSymbolArgsTemplate !!js/function >\n (_, pattern, flags) => {\n if (flags === null || flags === undefined) {\n flags = '';\n }\n if (\n (flags.charAt(0) === '\\'' && flags.charAt(flags.length - 1) === '\\'') ||\n (flags.charAt(0) === '\"' && flags.charAt(flags.length - 1) === '\"')) {\n flags = flags.substr(1, flags.length - 2);\n }\n // Double-quote stringify\n let newPat = pattern;\n if (\n (pattern.charAt(0) === '\\'' && pattern.charAt(pattern.length - 1) === '\\'') ||\n (pattern.charAt(0) === '\"' && pattern.charAt(pattern.length - 1) === '\"')) {\n newPat = pattern.substr(1, pattern.length - 2);\n }\n return ` { pattern: \"${newPat.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\", flags: \"${flags}\" }`;\n }\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate null # No args\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate null # Args: lhs, arg\n MinKeySymbolTemplate: &MinKeySymbolTemplate !!js/function >\n () => 'Bson::MinKey'\n MinKeySymbolArgsTemplate: &MinKeySymbolArgsTemplate !!js/function >\n () => ''\n MaxKeySymbolTemplate: &MaxKeySymbolTemplate !!js/function >\n () => 'Bson::MaxKey'\n MaxKeySymbolArgsTemplate: &MaxKeySymbolArgsTemplate !!js/function >\n () => ''\n TimestampSymbolTemplate: &TimestampSymbolTemplate !!js/function >\n () => 'Timestamp'\n TimestampSymbolArgsTemplate: &TimestampSymbolArgsTemplate !!js/function >\n (lhs, low, high) => {\n if (low === undefined) {\n low = 0;\n high = 0;\n }\n return ` { time: ${low}, increment: ${high} }`\n }\n # non bson-specific\n NumberSymbolTemplate: &NumberSymbolTemplate !!js/function >\n () => ''\n NumberSymbolArgsTemplate: &NumberSymbolArgsTemplate !!js/function >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n switch(type) {\n case '_string':\n if (arg.indexOf('.') !== -1) {\n return `${arg}.parse::()?`;\n }\n return `${arg}.parse::()?`;\n case '_integer':\n case '_long':\n case '_decimal':\n return `${arg}`;\n default:\n return `f32::try_from(${arg})?`;\n }\n }\n DateSymbolTemplate: &DateSymbolTemplate !!js/function >\n () => 'DateTime'\n DateSymbolArgsTemplate: &DateSymbolArgsTemplate !!js/function >\n (lhs, date, isString) => {\n let toStr = isString ? '.to_rfc3339_string()' : '';\n if (date === null) {\n return `${lhs}::now()${toStr}`;\n }\n return `${lhs}::parse_rfc3339_str(\"${date.toISOString()}\")?${toStr}`;\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These're variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: &CodeCodeTemplate null\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: &CodeScopeTemplate !!js/function >\n (lhs) => `${lhs}.scope`\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: &ObjectIdToStringTemplate !!js/function >\n (lhs) => `${lhs}.to_hex()`\n ObjectIdToStringArgsTemplate: &ObjectIdToStringArgsTemplate !!js/function >\n () => ''\n ObjectIdEqualsTemplate: &ObjectIdEqualsTemplate !!js/function >\n (lhs) => `${lhs} == `\n ObjectIdEqualsArgsTemplate: &ObjectIdEqualsArgsTemplate !!js/function >\n (_, arg) => arg\n ObjectIdGetTimestampTemplate: &ObjectIdGetTimestampTemplate !!js/function >\n (lhs) => `${lhs}.timestamp()`\n ObjectIdGetTimestampArgsTemplate: &ObjectIdGetTimestampArgsTemplate !!js/function >\n () => ''\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate null\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n BinaryValueTemplate: &BinaryValueTemplate !!js/function >\n (arg) => `${arg}.bytes`\n BinaryValueArgsTemplate: &BinaryValueArgsTemplate !!js/function >\n () => ''\n BinaryLengthTemplate: &BinaryLengthTemplate !!js/function >\n (arg) => `${arg}.bytes.len()`\n BinaryLengthArgsTemplate: &BinaryLengthArgsTemplate !!js/function >\n () => ''\n BinaryToStringTemplate: &BinaryToStringTemplate !!js/function >\n (arg) => `format!(\"{}\", ${arg})`\n BinaryToStringArgsTemplate: &BinaryToStringArgsTemplate !!js/function >\n () => ''\n BinarySubtypeTemplate: &BinarySubtypeTemplate !!js/function >\n (arg) => `${arg}.subtype`\n BinarySubtypeArgsTemplate: &BinarySubtypeArgsTemplate !!js/function >\n () => ''\n DBRefGetDBTemplate: &DBRefGetDBTemplate null\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate null\n DBRefGetIdTemplate: &DBRefGetIdTemplate null\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate null\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate null\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate null\n DBRefToStringTemplate: &DBRefToStringTemplate null\n DBRefToStringArgsTemplate: &DBRefToStringArgsTemplate null\n DoubleValueOfTemplate: &DoubleValueOfTemplate null\n DoubleValueOfArgsTemplate: &DoubleValueOfArgsTemplate null\n Int32ValueOfTemplate: &Int32ValueOfTemplate null\n Int32ValueOfArgsTemplate: &Int32ValueOfArgsTemplate null\n Int32ToStringTemplate: &Int32ToStringTemplate null\n Int32ToStringArgsTemplate: &Int32ToStringArgsTemplate null\n LongEqualsTemplate: &LongEqualsTemplate !!js/function >\n (lhs) => `${lhs} == `\n LongEqualsArgsTemplate: &LongEqualsArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongToStringTemplate: &LongToStringTemplate !!js/function >\n (arg) => arg\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToIntTemplate: &LongToIntTemplate !!js/function >\n (arg) => `${arg} as i32`\n LongToIntArgsTemplate: &LongToIntArgsTemplate !!js/function >\n () => ''\n LongValueOfTemplate: &LongValueOfTemplate null\n LongValueOfArgsTemplate: &LongValueOfArgsTemplate null\n LongToNumberTemplate: &LongToNumberTemplate !!js/function >\n (arg) => `${arg} as f64`\n LongToNumberArgsTemplate: &LongToNumberArgsTemplate !!js/function >\n () => ''\n LongAddTemplate: &LongAddTemplate !!js/function >\n (lhs) => `${lhs} + `\n LongAddArgsTemplate: &LongAddArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongSubtractTemplate: &LongSubtractTemplate !!js/function >\n (lhs) => `${lhs} - `\n LongSubtractArgsTemplate: &LongSubtractArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongMultiplyTemplate: &LongMultiplyTemplate !!js/function >\n (lhs) => `${lhs} * `\n LongMultiplyArgsTemplate: &LongMultiplyArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongDivTemplate: &LongDivTemplate !!js/function >\n (lhs) => `${lhs} / `\n LongDivArgsTemplate: &LongDivArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongModuloTemplate: &LongModuloTemplate !!js/function >\n (lhs) => `${lhs} % `\n LongModuloArgsTemplate: &LongModuloArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongAndTemplate: &LongAndTemplate !!js/function >\n (lhs) => `${lhs} & `\n LongAndArgsTemplate: &LongAndArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongOrTemplate: &LongOrTemplate !!js/function >\n (lhs) => `${lhs} | `\n LongOrArgsTemplate: &LongOrArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongXorTemplate: &LongXorTemplate !!js/function >\n (lhs) => `${lhs} ^ `\n LongXorArgsTemplate: &LongXorArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongShiftLeftTemplate: &LongShiftLeftTemplate !!js/function >\n (lhs) => `${lhs} << `\n LongShiftLeftArgsTemplate: &LongShiftLeftArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongShiftRightTemplate: &LongShiftRightTemplate !!js/function >\n (lhs) => `${lhs} >> `\n LongShiftRightArgsTemplate: &LongShiftRightArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongCompareTemplate: &LongCompareTemplate !!js/function >\n (lhs) => `${lhs} - `\n LongCompareArgsTemplate: &LongCompareArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongIsOddTemplate: &LongIsOddTemplate !!js/function >\n (arg) => `${arg} % 2 == 1`\n LongIsOddArgsTemplate: &LongIsOddArgsTemplate !!js/function >\n () => ''\n LongIsZeroTemplate: &LongIsZeroTemplate !!js/function >\n (arg) => `${arg} == 0`\n LongIsZeroArgsTemplate: &LongIsZeroArgsTemplate !!js/function >\n () => ''\n LongIsNegativeTemplate: &LongIsNegativeTemplate !!js/function >\n (arg) => `${arg} < 0`\n LongIsNegativeArgsTemplate: &LongIsNegativeArgsTemplate !!js/function >\n () => ''\n LongNegateTemplate: &LongNegateTemplate !!js/function >\n () => '-'\n LongNegateArgsTemplate: &LongNegateArgsTemplate !!js/function >\n (arg) => arg\n LongNotTemplate: &LongNotTemplate !!js/function >\n () => '~'\n LongNotArgsTemplate: &LongNotArgsTemplate !!js/function >\n (arg) => arg\n LongNotEqualsTemplate: &LongNotEqualsTemplate !!js/function >\n (lhs) => `${lhs} != `\n LongNotEqualsArgsTemplate: &LongNotEqualsArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongGreaterThanTemplate: &LongGreaterThanTemplate !!js/function >\n (lhs) => `${lhs} > `\n LongGreaterThanArgsTemplate: &LongGreaterThanArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongGreaterThanOrEqualTemplate: &LongGreaterThanOrEqualTemplate !!js/function >\n (lhs) => `${lhs} >= `\n LongGreaterThanOrEqualArgsTemplate: &LongGreaterThanOrEqualArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongLessThanTemplate: &LongLessThanTemplate !!js/function >\n (lhs) => `${lhs} < `\n LongLessThanArgsTemplate: &LongLessThanArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongLessThanOrEqualTemplate: &LongLessThanOrEqualTemplate !!js/function >\n (lhs) => `${lhs} <= `\n LongLessThanOrEqualArgsTemplate: &LongLessThanOrEqualArgsTemplate !!js/function >\n (_, rhs) => rhs\n LongFloatApproxTemplate: &LongFloatApproxTemplate !!js/function >\n (arg) => `${arg} as f32`\n LongTopTemplate: &LongTopTemplate !!js/function >\n (arg) => `${arg} >> 32`\n LongBottomTemplate: &LongBottomTemplate !!js/function >\n (arg) => `${arg} & 0x0000ffff`\n TimestampToStringTemplate: &TimestampToStringTemplate !!js/function >\n (arg) => `${arg}.to_string()`\n TimestampToStringArgsTemplate: &TimestampToStringArgsTemplate !!js/function >\n () => ''\n TimestampEqualsTemplate: &TimestampEqualsTemplate !!js/function >\n (lhs) => `${lhs} == `\n TimestampEqualsArgsTemplate: &TimestampEqualsArgsTemplate !!js/function >\n (_, rhs) => rhs\n TimestampGetLowBitsTemplate: &TimestampGetLowBitsTemplate !!js/function >\n (arg) => `${arg}.time`\n TimestampGetLowBitsArgsTemplate: &TimestampGetLowBitsArgsTemplate !!js/function >\n () => ''\n TimestampGetHighBitsTemplate: &TimestampGetHighBitsTemplate !!js/function >\n (arg) => `${arg}.increment`\n TimestampGetHighBitsArgsTemplate: &TimestampGetHighBitsArgsTemplate !!js/function >\n () => ''\n TimestampTTemplate: &TimestampTTemplate !!js/function >\n (arg) => `${arg}.time`\n TimestampITemplate: &TimestampITemplate !!js/function >\n (arg) => `${arg}.increment`\n TimestampAsDateTemplate: &TimestampAsDateTemplate !!js/function >\n (arg) => `DateTime::from_millis(${arg}.time)`\n TimestampAsDateArgsTemplate: &TimestampAsDateArgsTemplate !!js/function >\n () => ''\n TimestampCompareTemplate: &TimestampCompareTemplate !!js/function >\n (arg) => `${arg}.cmp`\n TimestampCompareArgsTemplate: &TimestampCompareArgsTemplate !!js/function >\n (_, rhs) => `(${rhs})`\n TimestampNotEqualsTemplate: &TimestampNotEqualsTemplate !!js/function >\n (lhs) => `${lhs} != `\n TimestampNotEqualsArgsTemplate: &TimestampNotEqualsArgsTemplate !!js/function >\n (_, rhs) => rhs\n TimestampGreaterThanTemplate: &TimestampGreaterThanTemplate !!js/function >\n (lhs) => `${lhs} > `\n TimestampGreaterThanArgsTemplate: &TimestampGreaterThanArgsTemplate !!js/function >\n (_, rhs) => rhs\n TimestampGreaterThanOrEqualTemplate: &TimestampGreaterThanOrEqualTemplate !!js/function >\n (lhs) => `${lhs} >= `\n TimestampGreaterThanOrEqualArgsTemplate: &TimestampGreaterThanOrEqualArgsTemplate !!js/function >\n (_, rhs) => rhs\n TimestampLessThanTemplate: &TimestampLessThanTemplate !!js/function >\n (lhs) => `${lhs} < `\n TimestampLessThanArgsTemplate: &TimestampLessThanArgsTemplate !!js/function >\n (_, rhs) => rhs\n TimestampLessThanOrEqualTemplate: &TimestampLessThanOrEqualTemplate !!js/function >\n (lhs) => `${lhs} <= `\n TimestampLessThanOrEqualArgsTemplate: &TimestampLessThanOrEqualArgsTemplate !!js/function >\n (_, rhs) => rhs\n SymbolValueOfTemplate: &SymbolValueOfTemplate !!js/function >\n (arg) => `${arg}.as_symbol().unwrap()`\n SymbolValueOfArgsTemplate: &SymbolValueOfArgsTemplate !!js/function >\n () => ''\n SymbolInspectTemplate: &SymbolInspectTemplate !!js/function >\n (arg) => `format!(\"{:?}\", ${arg})`\n SymbolInspectArgsTemplate: &SymbolInspectArgsTemplate !!js/function >\n () => ''\n SymbolToStringTemplate: &SymbolToStringTemplate !!js/function >\n (arg) => `${arg}.as_symbol().unwrap()`\n SymbolToStringArgsTemplate: &SymbolToStringArgsTemplate !!js/function >\n () => ''\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate null\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # non bson-specific\n DateSymbolNowTemplate: &DateSymbolNowTemplate !!js/function >\n () => 'DateTime::now()'\n DateSymbolNowArgsTemplate: &DateSymbolNowArgsTemplate !!js/function >\n () => ''\n\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These're variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don't overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: &LongSymbolMaxTemplate !!js/function >\n () => 'i64::MAX'\n LongSymbolMaxArgsTemplate: &LongSymbolMaxArgsTemplate !!js/function >\n () => ''\n LongSymbolMinTemplate: &LongSymbolMinTemplate !!js/function >\n () => 'i64::MIN'\n LongSymbolMinArgsTemplate: &LongSymbolMinArgsTemplate !!js/function >\n () => ''\n LongSymbolZeroTemplate: &LongSymbolZeroTemplate !!js/function >\n () => '0i64'\n LongSymbolZeroArgsTemplate: &LongSymbolZeroArgsTemplate !!js/function >\n () => ''\n LongSymbolOneTemplate: &LongSymbolOneTemplate !!js/function >\n () => '1i64'\n LongSymbolOneArgsTemplate: &LongSymbolOneArgsTemplate !!js/function >\n () => ''\n LongSymbolNegOneTemplate: &LongSymbolNegOneTemplate !!js/function >\n () => '-1i64'\n LongSymbolNegOneArgsTemplate: &LongSymbolNegOneArgsTemplate !!js/function >\n () => ''\n LongSymbolFromBitsTemplate: &LongSymbolFromBitsTemplate !!js/function >\n () => ''\n LongSymbolFromBitsArgsTemplate: &LongSymbolFromBitsArgsTemplate !!js/function >\n (_, arg) => `${arg}i64`\n LongSymbolFromIntTemplate: &LongSymbolFromIntTemplate !!js/function >\n () => ''\n LongSymbolFromIntArgsTemplate: &LongSymbolFromIntArgsTemplate !!js/function >\n (_, arg) => `${arg}i64`\n LongSymbolFromNumberTemplate: &LongSymbolFromNumberTemplate !!js/function >\n () => ''\n LongSymbolFromNumberArgsTemplate: &LongSymbolFromNumberArgsTemplate !!js/function >\n (_, arg) => `${arg} as i64`\n LongSymbolFromStringTemplate: &LongSymbolFromStringTemplate !!js/function >\n () => ''\n LongSymbolFromStringArgsTemplate: &LongSymbolFromStringArgsTemplate !!js/function >\n (_, arg, radix) => {\n if (radix) {\n return `i64::from_str_radix(${arg}, ${radix})?`;\n }\n return `${arg}.parse::()?`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate null\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate null\n ObjectIdCreateFromHexStringTemplate: &ObjectIdCreateFromHexStringTemplate !!js/function >\n (lhs) => lhs\n ObjectIdCreateFromHexStringArgsTemplate: &ObjectIdCreateFromHexStringArgsTemplate !!js/function >\n (lhs, arg) => {\n // Double quote stringify\n let newArg = arg;\n if (\n (arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'') ||\n (arg.charAt(0) === '\"' && arg.charAt(arg.length - 1) === '\"')) {\n newArg = arg.substr(1, arg.length - 2);\n }\n newArg = `\"${newArg.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n return `::parse_str(${newArg})?`;\n }\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate null\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate null\n # non bson-specific would go here, but there aren't any atm.\n\n #############################################\n # Imports #\n # #\n # Each type has a 'code' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: &ImportTemplate !!js/function >\n (args) => {\n let merged = new Set(Object.values(args));\n return [...merged].sort().join('\\n');\n }\n DriverImportTemplate: &DriverImportTemplate !!js/function >\n () => 'use mongodb::Client;'\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: &8ImportTemplate !!js/function >\n () => 'use mongodb::bson::Regex;'\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: &10ImportTemplate !!js/function >\n () => 'use mongodb::bson::doc;'\n # Null\n 11ImportTemplate: &11ImportTemplate !!js/function >\n () => 'use mongodb::bson::Bson;'\n # Undefined\n 12ImportTemplate: &12ImportTemplate !!js/function >\n () => 'use mongodb::bson::Bson;'\n # Code\n 100ImportTemplate: &100ImportTemplate !!js/function >\n () => 'use mongodb::bson::Bson;'\n 101ImportTemplate: &101ImportTemplate !!js/function >\n () => 'use mongodb::bson::oid::ObjectId;'\n 102ImportTemplate: &102ImportTemplate !!js/function >\n () => 'use mongodb::bson::Binary;'\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n # MinKey\n 107ImportTemplate: &107ImportTemplate !!js/function >\n () => 'use mongodb::bson::Bson;'\n # MaxKey\n 108ImportTemplate: &108ImportTemplate !!js/function >\n () => 'use mongodb::bson::Bson;'\n 109ImportTemplate: &109ImportTemplate !!js/function >\n () => 'use mongodb::bson::Regex;'\n 110ImportTemplate: &110ImportTemplate !!js/function >\n () => 'use mongodb::bson::Timestamp;'\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: &112ImportTemplate null\n 113ImportTemplate: &113ImportTemplate !!js/function >\n () => 'use mongodb::bson::JavaScriptCodeWithScope;'\n 114ImportTemplate: &114ImportTemplate !!js/function >\n () => 'use mongodb::bson::spec::BinarySubtype;'\n 200ImportTemplate: &200ImportTemplate !!js/function >\n () => 'use mongodb::bson::DateTime;'\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; +module.exports = + "SymbolTypes:\n VAR: &var 0\n CONSTRUCTOR: &constructor 1\n FUNC: &func 2\n# Internal patterns to save typing\n__type: &__type\n id: null\n callable: *var\n args: null\n type: null\n attr: {}\n template: null\n argsTemplate: null\n__func: &__func\n callable: *func\n args: []\n attr: {}\n template: null\n argsTemplate: null\n#############################################\n# Sample Templates #\n# #\n# The expected arguments are commented next #\n# to the template itself. Currently all are #\n# set to null, but to define a function #\n# replace 'null' with '!!js/function > \\n #\n# and a function defined below. #\n# #\n# See the other template files for examples #\n# #\n# Good to know: #\n# lhs is left-hand-side of the expression #\n# rhs is right-hand-side of the expression #\n# All args are strings unless noted #\n# - arg? is boolean #\n# - arg# is number #\n# #\n#############################################\nTemplates:\n ########\n # Misc #\n ########\n\n # Filter out regex flags that have translations or are unsupported.\n RegexFlags: &RegexFlags\n i: 'i'\n m: 'm'\n u: 'u'\n y: ''\n g: ''\n BSONRegexFlags: &BSONRegexFlags\n i: 'i'\n m: 'm'\n x: 'x'\n s: 's'\n l: 'l'\n u: 'u'\n\n #############################################\n # Syntax #\n # #\n # Templates for language syntax expressions #\n # #\n #############################################\n\n DriverTemplate: !!js/function &DriverTemplate >\n (spec) => {\n const comment = `// Requires the MongoDB crate.\\n// https://crates.io/crates/mongodb`;\n \n const options = spec.options;\n const filter = spec.filter || 'None';\n const exportMode = spec.exportMode;\n delete spec.options;\n delete spec.filter;\n delete spec.exportMode;\n\n const connect = `let client = Client::with_uri_str(\"${options.uri}\").await?;`\n const coll = `client.database(\"${options.database}\").collection::(\"${options.collection}\")`;\n\n if ('aggregation' in spec) {\n let agg = spec.aggregation;\n if (agg.charAt(0) != '[') {\n agg = `[${agg}]`;\n }\n return `${comment}\\n\\n${connect}\\nlet result = ${coll}.aggregate(${agg}, None).await?;`;\n }\n\n let driverMethod;\n let optionsName;\n switch (exportMode) {\n case 'Delete Query':\n driverMethod = 'delete_many';\n optionsName = 'DeleteOptions';\n break;\n case 'Update Query':\n driverMethod = 'update_many';\n optionsName = 'UpdateOptions';\n break;\n default:\n driverMethod = 'find';\n optionsName = 'FindOptions';\n break;\n }\n\n const findOpts = [];\n for (const k in spec) {\n let optName = k;\n let optValue = spec[k];\n switch(k) {\n case 'project':\n optName = 'projection';\n break;\n case 'maxTimeMS':\n optName = 'max_time';\n optValue = `std::time::Duration::from_millis(${optValue})`;\n break;\n }\n findOpts.push(` .${optName}(${optValue})`);\n }\n let optStr = '';\n if (findOpts.length > 0) {\n optStr = `let options = mongodb::options::${optionsName}::builder()\\n${findOpts.join('\\n')}\\n .build();\\n`;\n }\n let optRef = optStr ? 'options' : 'None';\n const cmd = `let result = ${coll}.${driverMethod}(${filter}, ${optRef}).await?;`;\n\n return `${comment}\\n\\n${connect}\\n${optStr}${cmd}`;\n }\n EqualitySyntaxTemplate: !!js/function &EqualitySyntaxTemplate >\n (lhs, op, rhs) => {\n if (op.includes('!') || op.includes('not')) {\n return `${lhs} != ${rhs}`;\n }\n else if (op === '==' || op === '===' || op === 'is') {\n return `${lhs} == ${rhs}`;\n }\n return `${lhs} ${op} ${rhs}`;\n }\n InSyntaxTemplate: !!js/function &InSyntaxTemplate >\n (lhs, op, rhs) => {\n let prefix = '';\n if (op.includes('!') || op.includes('not')) {\n prefix = '!';\n }\n return `${prefix}${rhs}.contains(&${lhs})`\n }\n AndSyntaxTemplate: !!js/function &AndSyntaxTemplate >\n (args) => {\n return args.join(' && ');\n }\n OrSyntaxTemplate: !!js/function &OrSyntaxTemplate >\n (args) => {\n return args.join(' || ');\n }\n NotSyntaxTemplate: !!js/function &NotSyntaxTemplate >\n (arg) => {\n return `!${arg}`;\n }\n UnarySyntaxTemplate: !!js/function &UnarySyntaxTemplate >\n (op, val) => {\n switch(op) {\n case '+':\n return val;\n case '~':\n return `!${val}`;\n default:\n return `${op}${val}`;\n }\n return `${op}${val}`;\n }\n BinarySyntaxTemplate: !!js/function &BinarySyntaxTemplate >\n (args) => {\n return args.reduce((s, op, i, arr) => {\n if (i % 2 === 0) {\n return s;\n }\n const rhs = arr[i + 1];\n switch(op) {\n case '//':\n return `${s} / ${rhs}`\n case '**':\n return `${s}.pow(${rhs})`\n default:\n return `${s} ${op} ${rhs}`;\n }\n }, args[0]);\n }\n ParensSyntaxTemplate: &ParensSyntaxTemplate null\n EosTemplate: &EosSyntaxTemplate null # No args. End-of-line\n EofTemplate: &EofSyntaxTemplate null # No args. End-of-file\n FloorDivTemplate: &FloorDivSyntaxTemplate null # Args: lhs, rhs\n PowerTemplate: &PowerSyntaxTemplate null # Args: lhs, rhs\n NewTemplate: &NewSyntaxTemplate null # Args: expression, skip?, code# [to check if meant to be skipped]\n\n #############################################\n # Literal Types #\n # #\n # Templates for literal type instance. Most #\n # get passed the literal itself as an arg. #\n # #\n #############################################\n StringTypeTemplate: !!js/function &StringTypeTemplate >\n (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n RegexTypeTemplate: !!js/function &RegexTypeTemplate >\n (pattern, flags) => {\n // Double-quote stringify\n let newPat = pattern;\n if (\n (pattern.charAt(0) === '\\'' && pattern.charAt(pattern.length - 1) === '\\'') ||\n (pattern.charAt(0) === '\"' && pattern.charAt(pattern.length - 1) === '\"')) {\n newPat = pattern.substr(1, pattern.length - 2);\n }\n return `Regex { pattern: \"${newPat.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\".to_string(), options: \"${flags}\".to_string() }`;\n }\n BoolTypeTemplate: !!js/function &BoolTypeTemplate >\n (literal) => {\n return literal.toLowerCase();\n }\n IntegerTypeTemplate: &IntegerTypeTemplate null # args: literal, argType (i.e. '_string', '_decimal' etc)\n DecimalTypeTemplate: &DecimalTypeTemplate null # args: literal, argType\n LongBasicTypeTemplate: &LongBasicTypeTemplate null\n HexTypeTemplate: !!js/function &HexTypeTemplate >\n (literal, type) => {\n if (literal.charAt(1) === 'X') {\n return literal.charAt(0) + 'x' + literal.substring(2);\n }\n return literal;\n }\n OctalTypeTemplate: !!js/function &OctalTypeTemplate >\n (literal, type) => {\n switch(literal.charAt(1)) {\n case 'o':\n return literal;\n case 'O':\n case '0':\n return literal.charAt(0) + 'o' + literal.substring(2);\n default:\n return literal.charAt(0) + 'o' + literal.substring(1);\n }\n }\n NumericTypeTemplate: &NumericTypeTemplate null # args: literal, argType\n ArrayTypeTemplate: !!js/function &ArrayTypeTemplate >\n (literal, depth) => {\n if (literal === '') {\n return '[]'\n }\n return `[${literal}]`;\n }\n ArrayTypeArgsTemplate: !!js/function &ArrayTypeArgsTemplate >\n (element, depth, isLast) => {\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = isLast ? '\\n' + ' '.repeat(depth - 1) : ',';\n return `${indent}${element}${closingIndent}`;\n }\n NullTypeTemplate: !!js/function &NullTypeTemplate >\n () => 'Bson::Null'\n UndefinedTypeTemplate: !!js/function &UndefinedTypeTemplate >\n () => 'Bson::Undefined'\n ObjectTypeTemplate: !!js/function &ObjectTypeTemplate >\n (literal) => `doc! {${literal}}`\n ObjectTypeArgsTemplate: !!js/function &ObjectTypeArgsTemplate >\n (args, depth) => {\n if (args.length === 0) {\n return '';\n }\n depth++;\n const indent = '\\n' + ' '.repeat(depth);\n const closingIndent = '\\n' + ' '.repeat(depth - 1);\n const doubleStringify = (str) => {\n let newStr = str;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n return `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n }\n\n const pairs = args.map((pair) => {\n return `${indent}${doubleStringify(pair[0])}: ${pair[1]}`;\n }).join(',');\n\n return `${pairs}${closingIndent}`;\n\n }\n\n #############################################\n # Symbols #\n # #\n # Templates for symbols, can be either #\n # functions or variables. #\n # #\n # The *SymbolTemplates return names and #\n # usually don't take any arguments. The #\n # *SymbolArgsTemplates are invoked for func #\n # calls. The first argument is always the #\n # lhs, i.e. the symbol returned from the #\n # corresponding SymbolTemplate. The rest of #\n # the arguments are the processed arguments #\n # passed to the original function. #\n # #\n #############################################\n CodeSymbolTemplate: !!js/function &CodeSymbolTemplate >\n () => ''\n CodeSymbolArgsTemplate: !!js/function &CodeSymbolArgsTemplate >\n (lhs, code, scope) => {\n // Double quote stringify\n let newStr = code === undefined ? '' : code;\n const str = newStr;\n if (\n (str.charAt(0) === '\\'' && str.charAt(str.length - 1) === '\\'') ||\n (str.charAt(0) === '\"' && str.charAt(str.length - 1) === '\"')) {\n newStr = str.substr(1, str.length - 2);\n }\n code = `\"${newStr.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\".to_string()`;\n if (scope === undefined) {\n return `Bson::JavaScriptCode(${code})`;\n } else {\n return `JavaScriptCodeWithScope { code: ${code}, scope: ${scope} }`;\n }\n }\n ObjectIdSymbolTemplate: !!js/function &ObjectIdSymbolTemplate >\n () => 'ObjectId'\n ObjectIdSymbolArgsTemplate: !!js/function &ObjectIdSymbolArgsTemplate >\n (lhs, arg) => {\n if (arg === undefined || arg === '') {\n return '::new()';\n }\n // Double quote stringify\n let newArg = arg;\n if (\n (arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'') ||\n (arg.charAt(0) === '\"' && arg.charAt(arg.length - 1) === '\"')) {\n newArg = arg.substr(1, arg.length - 2);\n }\n newArg = `\"${newArg.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n return `::parse_str(${newArg})?`;\n }\n BinarySymbolTemplate: &BinarySymbolTemplate null\n BinarySymbolArgsTemplate: &BinarySymbolArgsTemplate null\n BinarySymbolSubtypeDefaultTemplate:\n !!js/function &BinarySymbolSubtypeDefaultTemplate >\n () => 'BinarySubtype::Generic'\n BinarySymbolSubtypeFunctionTemplate:\n !!js/function &BinarySymbolSubtypeFunctionTemplate >\n () => 'BinarySubtype::Function'\n BinarySymbolSubtypeByteArrayTemplate:\n !!js/function &BinarySymbolSubtypeByteArrayTemplate >\n () => 'BinarySubtype::BinaryOld'\n BinarySymbolSubtypeUuidOldTemplate:\n !!js/function &BinarySymbolSubtypeUuidOldTemplate >\n () => 'BinarySubtype::UuidOld'\n BinarySymbolSubtypeUuidTemplate:\n !!js/function &BinarySymbolSubtypeUuidTemplate >\n () => 'BinarySubtype::Uuid'\n BinarySymbolSubtypeMd5Template:\n !!js/function &BinarySymbolSubtypeMd5Template >\n () => 'BinarySubtype::Md5'\n BinarySymbolSubtypeUserDefinedTemplate:\n !!js/function &BinarySymbolSubtypeUserDefinedTemplate >\n (arg) => `BinarySubtype::UserDefined(${arg})`\n DBRefSymbolTemplate: &DBRefSymbolTemplate null # No args\n DBRefSymbolArgsTemplate: &DBRefSymbolArgsTemplate null # Args: lhs, coll, id, db\n DoubleSymbolTemplate: !!js/function &DoubleSymbolTemplate >\n () => ''\n DoubleSymbolArgsTemplate: !!js/function &DoubleSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_decimal' || type === '_double') {\n return arg;\n }\n if (type === '_integer' || type === '_long') {\n return `${arg}.0`;\n }\n if (type === '_string') {\n return `${arg}.parse::()?`;\n }\n return `f32::try_from(${arg})?`;\n }\n Int32SymbolTemplate: !!js/function &Int32SymbolTemplate >\n () => ''\n Int32SymbolArgsTemplate: !!js/function &Int32SymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long' || type === '_hex' || type === '_octal') {\n return arg;\n }\n if (type === '_string') {\n return `${arg}.parse::()?`;\n }\n return `i32::try_from(${arg})?`;\n }\n LongSymbolTemplate: !!js/function &LongSymbolTemplate >\n () => ''\n LongSymbolArgsTemplate: !!js/function &LongSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n if (type === '_integer' || type === '_long' || type === '_hex' || type === '_octal') {\n return `${arg}i64`;\n }\n if (type === '_string') {\n return `${arg}.parse::()?`;\n }\n return `i64::try_from(${arg})?`;\n }\n RegExpSymbolTemplate: !!js/function &RegExpSymbolTemplate >\n () => 'Regex'\n RegExpSymbolArgsTemplate: &RegExpSymbolArgsTemplate null # Args: lhs, pattern, flags\n SymbolSymbolTemplate: !!js/function &SymbolSymbolTemplate >\n () => 'Bson::Symbol'\n SymbolSymbolArgsTemplate: !!js/function &SymbolSymbolArgsTemplate >\n (_, arg) => `(${arg})`\n BSONRegExpSymbolTemplate: !!js/function &BSONRegExpSymbolTemplate >\n () => 'Regex'\n BSONRegExpSymbolArgsTemplate: !!js/function &BSONRegExpSymbolArgsTemplate >\n (_, pattern, flags) => {\n if (flags === null || flags === undefined) {\n flags = '';\n }\n if (\n (flags.charAt(0) === '\\'' && flags.charAt(flags.length - 1) === '\\'') ||\n (flags.charAt(0) === '\"' && flags.charAt(flags.length - 1) === '\"')) {\n flags = flags.substr(1, flags.length - 2);\n }\n // Double-quote stringify\n let newPat = pattern;\n if (\n (pattern.charAt(0) === '\\'' && pattern.charAt(pattern.length - 1) === '\\'') ||\n (pattern.charAt(0) === '\"' && pattern.charAt(pattern.length - 1) === '\"')) {\n newPat = pattern.substr(1, pattern.length - 2);\n }\n return ` { pattern: \"${newPat.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\", flags: \"${flags}\" }`;\n }\n Decimal128SymbolTemplate: &Decimal128SymbolTemplate null # No args\n Decimal128SymbolArgsTemplate: &Decimal128SymbolArgsTemplate null # Args: lhs, arg\n MinKeySymbolTemplate: !!js/function &MinKeySymbolTemplate >\n () => 'Bson::MinKey'\n MinKeySymbolArgsTemplate: !!js/function &MinKeySymbolArgsTemplate >\n () => ''\n MaxKeySymbolTemplate: !!js/function &MaxKeySymbolTemplate >\n () => 'Bson::MaxKey'\n MaxKeySymbolArgsTemplate: !!js/function &MaxKeySymbolArgsTemplate >\n () => ''\n TimestampSymbolTemplate: !!js/function &TimestampSymbolTemplate >\n () => 'Timestamp'\n TimestampSymbolArgsTemplate: !!js/function &TimestampSymbolArgsTemplate >\n (lhs, low, high) => {\n if (low === undefined) {\n low = 0;\n high = 0;\n }\n return ` { time: ${low}, increment: ${high} }`\n }\n # non bson-specific\n NumberSymbolTemplate: !!js/function &NumberSymbolTemplate >\n () => ''\n NumberSymbolArgsTemplate: !!js/function &NumberSymbolArgsTemplate >\n (lhs, arg, type) => {\n arg = arg === undefined ? 0 : arg;\n\n switch(type) {\n case '_string':\n if (arg.indexOf('.') !== -1) {\n return `${arg}.parse::()?`;\n }\n return `${arg}.parse::()?`;\n case '_integer':\n case '_long':\n case '_decimal':\n return `${arg}`;\n default:\n return `f32::try_from(${arg})?`;\n }\n }\n DateSymbolTemplate: !!js/function &DateSymbolTemplate >\n () => 'DateTime'\n DateSymbolArgsTemplate: !!js/function &DateSymbolArgsTemplate >\n (lhs, date, isString) => {\n let toStr = isString ? '.to_rfc3339_string()' : '';\n if (date === null) {\n return `${lhs}::now()${toStr}`;\n }\n return `${lhs}::parse_rfc3339_str(\"${date.toISOString()}\")?${toStr}`;\n }\n\n #############################################\n # Object Attributes/Methods #\n # #\n # These're variables or functions called on #\n # instantiated objects. For example, #\n # ObjectId().isValid() or Timestamp().t #\n # #\n # They follow the same pattern with the\n # *Template/*ArgsTemplates: usually no args #\n # to the Template and lhs plus any original #\n # arguments to the ArgsTemplate. #\n # #\n #############################################\n CodeCodeTemplate: &CodeCodeTemplate null\n CodeCodeArgsTemplate: &CodeCodeArgsTemplate null\n CodeScopeTemplate: !!js/function &CodeScopeTemplate >\n (lhs) => `${lhs}.scope`\n CodeScopeArgsTemplate: &CodeScopeArgsTemplate null\n ObjectIdToStringTemplate: !!js/function &ObjectIdToStringTemplate >\n (lhs) => `${lhs}.to_hex()`\n ObjectIdToStringArgsTemplate: !!js/function &ObjectIdToStringArgsTemplate >\n () => ''\n ObjectIdEqualsTemplate: !!js/function &ObjectIdEqualsTemplate >\n (lhs) => `${lhs} == `\n ObjectIdEqualsArgsTemplate: !!js/function &ObjectIdEqualsArgsTemplate >\n (_, arg) => arg\n ObjectIdGetTimestampTemplate: !!js/function &ObjectIdGetTimestampTemplate >\n (lhs) => `${lhs}.timestamp()`\n ObjectIdGetTimestampArgsTemplate:\n !!js/function &ObjectIdGetTimestampArgsTemplate >\n () => ''\n ObjectIdIsValidTemplate: &ObjectIdIsValidTemplate null\n ObjectIdIsValidArgsTemplate: &ObjectIdIsValidArgsTemplate null\n BinaryValueTemplate: !!js/function &BinaryValueTemplate >\n (arg) => `${arg}.bytes`\n BinaryValueArgsTemplate: !!js/function &BinaryValueArgsTemplate >\n () => ''\n BinaryLengthTemplate: !!js/function &BinaryLengthTemplate >\n (arg) => `${arg}.bytes.len()`\n BinaryLengthArgsTemplate: !!js/function &BinaryLengthArgsTemplate >\n () => ''\n BinaryToStringTemplate: !!js/function &BinaryToStringTemplate >\n (arg) => `format!(\"{}\", ${arg})`\n BinaryToStringArgsTemplate: !!js/function &BinaryToStringArgsTemplate >\n () => ''\n BinarySubtypeTemplate: !!js/function &BinarySubtypeTemplate >\n (arg) => `${arg}.subtype`\n BinarySubtypeArgsTemplate: !!js/function &BinarySubtypeArgsTemplate >\n () => ''\n DBRefGetDBTemplate: &DBRefGetDBTemplate null\n DBRefGetCollectionTemplate: &DBRefGetCollectionTemplate null\n DBRefGetIdTemplate: &DBRefGetIdTemplate null\n DBRefGetDBArgsTemplate: &DBRefGetDBArgsTemplate null\n DBRefGetCollectionArgsTemplate: &DBRefGetCollectionArgsTemplate null\n DBRefGetIdArgsTemplate: &DBRefGetIdArgsTemplate null\n DBRefToStringTemplate: &DBRefToStringTemplate null\n DBRefToStringArgsTemplate: &DBRefToStringArgsTemplate null\n DoubleValueOfTemplate: &DoubleValueOfTemplate null\n DoubleValueOfArgsTemplate: &DoubleValueOfArgsTemplate null\n Int32ValueOfTemplate: &Int32ValueOfTemplate null\n Int32ValueOfArgsTemplate: &Int32ValueOfArgsTemplate null\n Int32ToStringTemplate: &Int32ToStringTemplate null\n Int32ToStringArgsTemplate: &Int32ToStringArgsTemplate null\n LongEqualsTemplate: !!js/function &LongEqualsTemplate >\n (lhs) => `${lhs} == `\n LongEqualsArgsTemplate: !!js/function &LongEqualsArgsTemplate >\n (_, rhs) => rhs\n LongToStringTemplate: !!js/function &LongToStringTemplate >\n (arg) => arg\n LongToStringArgsTemplate: &LongToStringArgsTemplate null\n LongToIntTemplate: !!js/function &LongToIntTemplate >\n (arg) => `${arg} as i32`\n LongToIntArgsTemplate: !!js/function &LongToIntArgsTemplate >\n () => ''\n LongValueOfTemplate: &LongValueOfTemplate null\n LongValueOfArgsTemplate: &LongValueOfArgsTemplate null\n LongToNumberTemplate: !!js/function &LongToNumberTemplate >\n (arg) => `${arg} as f64`\n LongToNumberArgsTemplate: !!js/function &LongToNumberArgsTemplate >\n () => ''\n LongAddTemplate: !!js/function &LongAddTemplate >\n (lhs) => `${lhs} + `\n LongAddArgsTemplate: !!js/function &LongAddArgsTemplate >\n (_, rhs) => rhs\n LongSubtractTemplate: !!js/function &LongSubtractTemplate >\n (lhs) => `${lhs} - `\n LongSubtractArgsTemplate: !!js/function &LongSubtractArgsTemplate >\n (_, rhs) => rhs\n LongMultiplyTemplate: !!js/function &LongMultiplyTemplate >\n (lhs) => `${lhs} * `\n LongMultiplyArgsTemplate: !!js/function &LongMultiplyArgsTemplate >\n (_, rhs) => rhs\n LongDivTemplate: !!js/function &LongDivTemplate >\n (lhs) => `${lhs} / `\n LongDivArgsTemplate: !!js/function &LongDivArgsTemplate >\n (_, rhs) => rhs\n LongModuloTemplate: !!js/function &LongModuloTemplate >\n (lhs) => `${lhs} % `\n LongModuloArgsTemplate: !!js/function &LongModuloArgsTemplate >\n (_, rhs) => rhs\n LongAndTemplate: !!js/function &LongAndTemplate >\n (lhs) => `${lhs} & `\n LongAndArgsTemplate: !!js/function &LongAndArgsTemplate >\n (_, rhs) => rhs\n LongOrTemplate: !!js/function &LongOrTemplate >\n (lhs) => `${lhs} | `\n LongOrArgsTemplate: !!js/function &LongOrArgsTemplate >\n (_, rhs) => rhs\n LongXorTemplate: !!js/function &LongXorTemplate >\n (lhs) => `${lhs} ^ `\n LongXorArgsTemplate: !!js/function &LongXorArgsTemplate >\n (_, rhs) => rhs\n LongShiftLeftTemplate: !!js/function &LongShiftLeftTemplate >\n (lhs) => `${lhs} << `\n LongShiftLeftArgsTemplate: !!js/function &LongShiftLeftArgsTemplate >\n (_, rhs) => rhs\n LongShiftRightTemplate: !!js/function &LongShiftRightTemplate >\n (lhs) => `${lhs} >> `\n LongShiftRightArgsTemplate: !!js/function &LongShiftRightArgsTemplate >\n (_, rhs) => rhs\n LongCompareTemplate: !!js/function &LongCompareTemplate >\n (lhs) => `${lhs} - `\n LongCompareArgsTemplate: !!js/function &LongCompareArgsTemplate >\n (_, rhs) => rhs\n LongIsOddTemplate: !!js/function &LongIsOddTemplate >\n (arg) => `${arg} % 2 == 1`\n LongIsOddArgsTemplate: !!js/function &LongIsOddArgsTemplate >\n () => ''\n LongIsZeroTemplate: !!js/function &LongIsZeroTemplate >\n (arg) => `${arg} == 0`\n LongIsZeroArgsTemplate: !!js/function &LongIsZeroArgsTemplate >\n () => ''\n LongIsNegativeTemplate: !!js/function &LongIsNegativeTemplate >\n (arg) => `${arg} < 0`\n LongIsNegativeArgsTemplate: !!js/function &LongIsNegativeArgsTemplate >\n () => ''\n LongNegateTemplate: !!js/function &LongNegateTemplate >\n () => '-'\n LongNegateArgsTemplate: !!js/function &LongNegateArgsTemplate >\n (arg) => arg\n LongNotTemplate: !!js/function &LongNotTemplate >\n () => '~'\n LongNotArgsTemplate: !!js/function &LongNotArgsTemplate >\n (arg) => arg\n LongNotEqualsTemplate: !!js/function &LongNotEqualsTemplate >\n (lhs) => `${lhs} != `\n LongNotEqualsArgsTemplate: !!js/function &LongNotEqualsArgsTemplate >\n (_, rhs) => rhs\n LongGreaterThanTemplate: !!js/function &LongGreaterThanTemplate >\n (lhs) => `${lhs} > `\n LongGreaterThanArgsTemplate: !!js/function &LongGreaterThanArgsTemplate >\n (_, rhs) => rhs\n LongGreaterThanOrEqualTemplate:\n !!js/function &LongGreaterThanOrEqualTemplate >\n (lhs) => `${lhs} >= `\n LongGreaterThanOrEqualArgsTemplate:\n !!js/function &LongGreaterThanOrEqualArgsTemplate >\n (_, rhs) => rhs\n LongLessThanTemplate: !!js/function &LongLessThanTemplate >\n (lhs) => `${lhs} < `\n LongLessThanArgsTemplate: !!js/function &LongLessThanArgsTemplate >\n (_, rhs) => rhs\n LongLessThanOrEqualTemplate: !!js/function &LongLessThanOrEqualTemplate >\n (lhs) => `${lhs} <= `\n LongLessThanOrEqualArgsTemplate:\n !!js/function &LongLessThanOrEqualArgsTemplate >\n (_, rhs) => rhs\n LongFloatApproxTemplate: !!js/function &LongFloatApproxTemplate >\n (arg) => `${arg} as f32`\n LongTopTemplate: !!js/function &LongTopTemplate >\n (arg) => `${arg} >> 32`\n LongBottomTemplate: !!js/function &LongBottomTemplate >\n (arg) => `${arg} & 0x0000ffff`\n TimestampToStringTemplate: !!js/function &TimestampToStringTemplate >\n (arg) => `${arg}.to_string()`\n TimestampToStringArgsTemplate: !!js/function &TimestampToStringArgsTemplate >\n () => ''\n TimestampEqualsTemplate: !!js/function &TimestampEqualsTemplate >\n (lhs) => `${lhs} == `\n TimestampEqualsArgsTemplate: !!js/function &TimestampEqualsArgsTemplate >\n (_, rhs) => rhs\n TimestampGetLowBitsTemplate: !!js/function &TimestampGetLowBitsTemplate >\n (arg) => `${arg}.time`\n TimestampGetLowBitsArgsTemplate:\n !!js/function &TimestampGetLowBitsArgsTemplate >\n () => ''\n TimestampGetHighBitsTemplate: !!js/function &TimestampGetHighBitsTemplate >\n (arg) => `${arg}.increment`\n TimestampGetHighBitsArgsTemplate:\n !!js/function &TimestampGetHighBitsArgsTemplate >\n () => ''\n TimestampTTemplate: !!js/function &TimestampTTemplate >\n (arg) => `${arg}.time`\n TimestampITemplate: !!js/function &TimestampITemplate >\n (arg) => `${arg}.increment`\n TimestampAsDateTemplate: !!js/function &TimestampAsDateTemplate >\n (arg) => `DateTime::from_millis(${arg}.time)`\n TimestampAsDateArgsTemplate: !!js/function &TimestampAsDateArgsTemplate >\n () => ''\n TimestampCompareTemplate: !!js/function &TimestampCompareTemplate >\n (arg) => `${arg}.cmp`\n TimestampCompareArgsTemplate: !!js/function &TimestampCompareArgsTemplate >\n (_, rhs) => `(${rhs})`\n TimestampNotEqualsTemplate: !!js/function &TimestampNotEqualsTemplate >\n (lhs) => `${lhs} != `\n TimestampNotEqualsArgsTemplate:\n !!js/function &TimestampNotEqualsArgsTemplate >\n (_, rhs) => rhs\n TimestampGreaterThanTemplate: !!js/function &TimestampGreaterThanTemplate >\n (lhs) => `${lhs} > `\n TimestampGreaterThanArgsTemplate:\n !!js/function &TimestampGreaterThanArgsTemplate >\n (_, rhs) => rhs\n TimestampGreaterThanOrEqualTemplate:\n !!js/function &TimestampGreaterThanOrEqualTemplate >\n (lhs) => `${lhs} >= `\n TimestampGreaterThanOrEqualArgsTemplate:\n !!js/function &TimestampGreaterThanOrEqualArgsTemplate >\n (_, rhs) => rhs\n TimestampLessThanTemplate: !!js/function &TimestampLessThanTemplate >\n (lhs) => `${lhs} < `\n TimestampLessThanArgsTemplate: !!js/function &TimestampLessThanArgsTemplate >\n (_, rhs) => rhs\n TimestampLessThanOrEqualTemplate:\n !!js/function &TimestampLessThanOrEqualTemplate >\n (lhs) => `${lhs} <= `\n TimestampLessThanOrEqualArgsTemplate:\n !!js/function &TimestampLessThanOrEqualArgsTemplate >\n (_, rhs) => rhs\n SymbolValueOfTemplate: !!js/function &SymbolValueOfTemplate >\n (arg) => `${arg}.as_symbol().unwrap()`\n SymbolValueOfArgsTemplate: !!js/function &SymbolValueOfArgsTemplate >\n () => ''\n SymbolInspectTemplate: !!js/function &SymbolInspectTemplate >\n (arg) => `format!(\"{:?}\", ${arg})`\n SymbolInspectArgsTemplate: !!js/function &SymbolInspectArgsTemplate >\n () => ''\n SymbolToStringTemplate: !!js/function &SymbolToStringTemplate >\n (arg) => `${arg}.as_symbol().unwrap()`\n SymbolToStringArgsTemplate: !!js/function &SymbolToStringArgsTemplate >\n () => ''\n Decimal128ToStringTemplate: &Decimal128ToStringTemplate null\n Decimal128ToStringArgsTemplate: &Decimal128ToStringArgsTemplate null\n # non bson-specific\n DateSymbolNowTemplate: !!js/function &DateSymbolNowTemplate >\n () => 'DateTime::now()'\n DateSymbolNowArgsTemplate: !!js/function &DateSymbolNowArgsTemplate >\n () => ''\n\n #############################################\n # Symbol Attributes/Methods #\n # #\n # These're variables or functions called on #\n # symbols. Also called bson-utils. #\n # #\n # They are basically the same thing as #\n # object attributes/methods, but need to be #\n # distinguished since they are separate #\n # namespaces that happen to have the same #\n # name which is v confusing. #\n # #\n # For example, ObjectId().toString() is an #\n # object method, while ObjectId.fromString #\n # is a symbol attribute. These are two #\n # separate ObjectId related namespaces that #\n # don't overlap. #\n # #\n #############################################\n LongSymbolMaxTemplate: !!js/function &LongSymbolMaxTemplate >\n () => 'i64::MAX'\n LongSymbolMaxArgsTemplate: !!js/function &LongSymbolMaxArgsTemplate >\n () => ''\n LongSymbolMinTemplate: !!js/function &LongSymbolMinTemplate >\n () => 'i64::MIN'\n LongSymbolMinArgsTemplate: !!js/function &LongSymbolMinArgsTemplate >\n () => ''\n LongSymbolZeroTemplate: !!js/function &LongSymbolZeroTemplate >\n () => '0i64'\n LongSymbolZeroArgsTemplate: !!js/function &LongSymbolZeroArgsTemplate >\n () => ''\n LongSymbolOneTemplate: !!js/function &LongSymbolOneTemplate >\n () => '1i64'\n LongSymbolOneArgsTemplate: !!js/function &LongSymbolOneArgsTemplate >\n () => ''\n LongSymbolNegOneTemplate: !!js/function &LongSymbolNegOneTemplate >\n () => '-1i64'\n LongSymbolNegOneArgsTemplate: !!js/function &LongSymbolNegOneArgsTemplate >\n () => ''\n LongSymbolFromBitsTemplate: !!js/function &LongSymbolFromBitsTemplate >\n () => ''\n LongSymbolFromBitsArgsTemplate:\n !!js/function &LongSymbolFromBitsArgsTemplate >\n (_, arg) => `${arg}i64`\n LongSymbolFromIntTemplate: !!js/function &LongSymbolFromIntTemplate >\n () => ''\n LongSymbolFromIntArgsTemplate: !!js/function &LongSymbolFromIntArgsTemplate >\n (_, arg) => `${arg}i64`\n LongSymbolFromNumberTemplate: !!js/function &LongSymbolFromNumberTemplate >\n () => ''\n LongSymbolFromNumberArgsTemplate:\n !!js/function &LongSymbolFromNumberArgsTemplate >\n (_, arg) => `${arg} as i64`\n LongSymbolFromStringTemplate: !!js/function &LongSymbolFromStringTemplate >\n () => ''\n LongSymbolFromStringArgsTemplate:\n !!js/function &LongSymbolFromStringArgsTemplate >\n (_, arg, radix) => {\n if (radix) {\n return `i64::from_str_radix(${arg}, ${radix})?`;\n }\n return `${arg}.parse::()?`;\n }\n Decimal128SymbolFromStringTemplate: &Decimal128SymbolFromStringTemplate null\n Decimal128SymbolFromStringArgsTemplate: &Decimal128SymbolFromStringArgsTemplate null\n ObjectIdCreateFromHexStringTemplate:\n !!js/function &ObjectIdCreateFromHexStringTemplate >\n (lhs) => lhs\n ObjectIdCreateFromHexStringArgsTemplate:\n !!js/function &ObjectIdCreateFromHexStringArgsTemplate >\n (lhs, arg) => {\n // Double quote stringify\n let newArg = arg;\n if (\n (arg.charAt(0) === '\\'' && arg.charAt(arg.length - 1) === '\\'') ||\n (arg.charAt(0) === '\"' && arg.charAt(arg.length - 1) === '\"')) {\n newArg = arg.substr(1, arg.length - 2);\n }\n newArg = `\"${newArg.replace(/\\\\([\\s\\S])|(\")/g, '\\\\$1$2')}\"`;\n return `::parse_str(${newArg})?`;\n }\n ObjectIdCreateFromTimeTemplate: &ObjectIdCreateFromTimeTemplate null\n ObjectIdCreateFromTimeArgsTemplate: &ObjectIdCreateFromTimeArgsTemplate null\n # non bson-specific would go here, but there aren't any atm.\n\n #############################################\n # Imports #\n # #\n # Each type has a 'code' that is consistent #\n # between languages. The import templates #\n # for each code generate the required #\n # statement for each type. No args. #\n # #\n # The ImportTemplate collects everything #\n # into one statement. #\n # #\n #############################################\n ImportTemplate: !!js/function &ImportTemplate >\n (args) => {\n let merged = new Set(Object.values(args));\n return [...merged].sort().join('\\n');\n }\n DriverImportTemplate: !!js/function &DriverImportTemplate >\n () => 'use mongodb::Client;'\n 0ImportTemplate: &0ImportTemplate null\n 1ImportTemplate: &1ImportTemplate null\n 2ImportTemplate: &2ImportTemplate null\n 3ImportTemplate: &3ImportTemplate null\n 4ImportTemplate: &4ImportTemplate null\n 5ImportTemplate: &5ImportTemplate null\n 6ImportTemplate: &6ImportTemplate null\n 7ImportTemplate: &7ImportTemplate null\n 8ImportTemplate: !!js/function &8ImportTemplate >\n () => 'use mongodb::bson::Regex;'\n 9ImportTemplate: &9ImportTemplate null\n 10ImportTemplate: !!js/function &10ImportTemplate >\n () => 'use mongodb::bson::doc;'\n # Null\n 11ImportTemplate: !!js/function &11ImportTemplate >\n () => 'use mongodb::bson::Bson;'\n # Undefined\n 12ImportTemplate: !!js/function &12ImportTemplate >\n () => 'use mongodb::bson::Bson;'\n # Code\n 100ImportTemplate: !!js/function &100ImportTemplate >\n () => 'use mongodb::bson::Bson;'\n 101ImportTemplate: !!js/function &101ImportTemplate >\n () => 'use mongodb::bson::oid::ObjectId;'\n 102ImportTemplate: !!js/function &102ImportTemplate >\n () => 'use mongodb::bson::Binary;'\n 103ImportTemplate: &103ImportTemplate null\n 104ImportTemplate: &104ImportTemplate null\n 105ImportTemplate: &105ImportTemplate null\n 106ImportTemplate: &106ImportTemplate null\n # MinKey\n 107ImportTemplate: !!js/function &107ImportTemplate >\n () => 'use mongodb::bson::Bson;'\n # MaxKey\n 108ImportTemplate: !!js/function &108ImportTemplate >\n () => 'use mongodb::bson::Bson;'\n 109ImportTemplate: !!js/function &109ImportTemplate >\n () => 'use mongodb::bson::Regex;'\n 110ImportTemplate: !!js/function &110ImportTemplate >\n () => 'use mongodb::bson::Timestamp;'\n 111ImportTemplate: &111ImportTemplate null\n 112ImportTemplate: &112ImportTemplate null\n 113ImportTemplate: !!js/function &113ImportTemplate >\n () => 'use mongodb::bson::JavaScriptCodeWithScope;'\n 114ImportTemplate: !!js/function &114ImportTemplate >\n () => 'use mongodb::bson::spec::BinarySubtype;'\n 200ImportTemplate: !!js/function &200ImportTemplate >\n () => 'use mongodb::bson::DateTime;'\n 201ImportTemplate: &201ImportTemplate null\n 300ImportTemplate: &300ImportTemplate null\n 301ImportTemplate: &301ImportTemplate null\n 302ImportTemplate: &302ImportTemplate null\n 303ImportTemplate: &303ImportTemplate null\n 304ImportTemplate: &304ImportTemplate null\n 305ImportTemplate: &305ImportTemplate null\n 306ImportTemplate: &306ImportTemplate null\n# Universal types\n# Everything inherits from StringType because we haven't implemented any of them.\nBasicTypes:\n # Universal basic types\n _bool: &BoolType\n <<: *__type\n id: \"_bool\"\n code: 0\n template: *BoolTypeTemplate\n _integer: &IntegerType\n <<: *__type\n id: \"_integer\"\n code: 1\n template: *IntegerTypeTemplate\n _long: &LongBasicType\n <<: *__type\n id: \"_long\"\n code: 2\n template: *LongBasicTypeTemplate\n _decimal: &DecimalType\n <<: *__type\n id: \"_decimal\"\n code: 3\n template: *DecimalTypeTemplate\n _hex: &HexType\n <<: *__type\n id: \"_hex\"\n code: 4\n template: *HexTypeTemplate\n _octal: &OctalType\n <<: *__type\n id: \"_octal\"\n code: 5\n template: *OctalTypeTemplate\n _numeric: &NumericType\n <<: *__type\n id: \"_numeric\"\n code: 6\n template: *NumericTypeTemplate\n _string: &StringType\n <<: *__type\n id: \"_string\"\n code: 7\n template: *StringTypeTemplate\n _regex: &RegexType\n <<: *__type\n id: \"_regex\"\n code: 8\n template: *RegexTypeTemplate\n _array: &ArrayType\n <<: *__type\n id: \"_array\"\n code: 9\n template: *ArrayTypeTemplate\n argsTemplate: *ArrayTypeArgsTemplate\n _object: &ObjectType\n <<: *__type\n id: \"_object\"\n code: 10\n template: *ObjectTypeTemplate\n argsTemplate: *ObjectTypeArgsTemplate\n _null: &NullType\n <<: *__type\n id: \"_null\"\n code: 11\n template: *NullTypeTemplate\n _undefined: &UndefinedType\n <<: *__type\n id: \"_undefined\"\n code: 12\n template: *UndefinedTypeTemplate\n\nSyntax:\n equality:\n template: *EqualitySyntaxTemplate\n in:\n template: *InSyntaxTemplate\n and:\n template: *AndSyntaxTemplate\n or:\n template: *OrSyntaxTemplate\n not:\n template: *NotSyntaxTemplate\n unary:\n template: *UnarySyntaxTemplate\n binary:\n template: *BinarySyntaxTemplate\n parens:\n template: *ParensSyntaxTemplate\n eos:\n template: *EosSyntaxTemplate\n eof:\n template: *EofSyntaxTemplate\n # The new template takes in expr, and an optional skip argument and optional\n # id argument. The skip argument is a boolean that if true then doesn't add\n # new. The code argument is the symbol code being called. The template will check\n # if it is an exception, i.e. a type that is a constructor but may not use new.\n new:\n template: *NewSyntaxTemplate\n # The regex flags that change symbols between languages can be defined here.\n # Flags that aren't defined can be left blank and will be ignored.\n regexFlags: *RegexFlags\n bsonRegexFlags: *BSONRegexFlags\n driver: *DriverTemplate\nImports:\n import:\n template: *ImportTemplate\n driver:\n template: *DriverImportTemplate\n 0:\n template: *0ImportTemplate\n 1:\n template: *1ImportTemplate\n 2:\n template: *2ImportTemplate\n 3:\n template: *3ImportTemplate\n 4:\n template: *4ImportTemplate\n 5:\n template: *5ImportTemplate\n 6:\n template: *6ImportTemplate\n 7:\n template: *7ImportTemplate\n 8:\n template: *8ImportTemplate\n 9:\n template: *9ImportTemplate\n 10:\n template: *10ImportTemplate\n 11:\n template: *11ImportTemplate\n 12:\n template: *12ImportTemplate\n 100:\n template: *100ImportTemplate\n 101:\n template: *101ImportTemplate\n 102:\n template: *102ImportTemplate\n 103:\n template: *103ImportTemplate\n 104:\n template: *104ImportTemplate\n 105:\n template: *105ImportTemplate\n 106:\n template: *106ImportTemplate\n 107:\n template: *107ImportTemplate\n 108:\n template: *108ImportTemplate\n 109:\n template: *109ImportTemplate\n 110:\n template: *110ImportTemplate\n 111:\n template: *111ImportTemplate\n 112:\n template: *112ImportTemplate\n 113:\n template: *113ImportTemplate\n 114:\n template: *114ImportTemplate\n 200:\n template: *200ImportTemplate\n 201:\n template: *201ImportTemplate\n 300:\n template: *300ImportTemplate\n 301:\n template: *301ImportTemplate\n 302:\n template: *302ImportTemplate\n 303:\n template: *303ImportTemplate\n 304:\n template: *304ImportTemplate\n 305:\n template: *305ImportTemplate\n 306:\n template: *306ImportTemplate\nBsonTypes:\n Code: &CodeType\n <<: *__type\n id: \"Code\"\n code: 100\n type: *ObjectType\n attr:\n code:\n callable: *var\n args: null\n attr: null\n id: \"code\"\n type: *StringType\n template: *CodeCodeTemplate\n argsTemplate: *CodeCodeArgsTemplate\n scope:\n callable: *var\n args: null\n attr: null\n id: \"scope\"\n type: *StringType\n template: *CodeScopeTemplate\n argsTemplate: *CodeScopeArgsTemplate\n ObjectId: &ObjectIdType\n <<: *__type\n id: \"ObjectId\"\n code: 101\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *ObjectIdToStringTemplate\n argsTemplate: *ObjectIdToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"ObjectId\" ]\n type: *BoolType\n template: *ObjectIdEqualsTemplate\n argsTemplate: *ObjectIdEqualsArgsTemplate\n getTimestamp:\n <<: *__func\n id: \"getTimestamp\"\n type: *IntegerType\n template: *ObjectIdGetTimestampTemplate\n argsTemplate: *ObjectIdGetTimestampArgsTemplate\n BinData: &BinaryType\n <<: *__type\n id: \"BinData\"\n code: 102\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *BinaryToStringTemplate\n argsTemplate: *BinaryToStringArgsTemplate\n base64:\n <<: *__func\n id: \"base64\"\n type: *StringType\n template: *BinaryValueTemplate\n argsTemplate: *BinaryValueArgsTemplate\n length:\n <<: *__func\n id: \"length\"\n type: *IntegerType\n template: *BinaryLengthTemplate\n argsTemplate: *BinaryLengthArgsTemplate\n subtype:\n <<: *__func\n id: \"subtype\"\n type: *IntegerType\n template: *BinarySubtypeTemplate\n argsTemplate: *BinarySubtypeArgsTemplate\n DBRef: &DBRefType\n <<: *__type\n id: \"DBRef\"\n code: 103\n type: *ObjectType\n attr:\n getDb:\n <<: *__func\n id: \"getDb\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n $db:\n callable: *var\n args: null\n attr: null\n id: \"$db\"\n type: *StringType\n template: *DBRefGetDBTemplate\n argsTemplate: *DBRefGetDBArgsTemplate\n getCollection:\n <<: *__func\n id: \"getCollection\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getRef:\n <<: *__func\n id: \"getRef\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n $ref:\n callable: *var\n args: null\n attr: null\n id: \"$ref\"\n type: *StringType\n template: *DBRefGetCollectionTemplate\n argsTemplate: *DBRefGetCollectionArgsTemplate\n getId:\n <<: *__func\n id: \"getId\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n $id:\n callable: *var\n args: null\n attr: null\n id: \"$id\"\n type: *StringType\n template: *DBRefGetIdTemplate\n argsTemplate: *DBRefGetIdArgsTemplate\n NumberInt: &Int32Type\n <<: *__type\n id: \"NumberInt\"\n code: 105\n type: *ObjectType\n attr: {}\n NumberLong: &LongType\n <<: *__type\n id: \"NumberLong\"\n code: 106\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"LongtoString\" # Needs process method\n args:\n - [ *IntegerType, null ]\n type: *StringType\n template: *LongToStringTemplate\n argsTemplate: *LongToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongEqualsTemplate\n argsTemplate: *LongEqualsArgsTemplate\n toInt:\n <<: *__func\n id: \"toInt\"\n type: *IntegerType\n template: *LongToIntTemplate\n argsTemplate: *LongToIntArgsTemplate\n toNumber:\n <<: *__func\n id: \"toNumber\"\n type: *DecimalType\n template: *LongToNumberTemplate\n argsTemplate: *LongToNumberArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Long\" ]\n type: *StringType\n template: *LongCompareTemplate\n argsTemplate: *LongCompareArgsTemplate\n isOdd:\n <<: *__func\n id: \"isOdd\"\n type: *BoolType\n template: *LongIsOddTemplate\n argsTemplate: *LongIsOddArgsTemplate\n isZero:\n <<: *__func\n id: \"isZero\"\n type: *BoolType\n template: *LongIsZeroTemplate\n argsTemplate: *LongIsZeroArgsTemplate\n isNegative:\n <<: *__func\n id: \"isNegative\"\n type: *BoolType\n template: *LongIsNegativeTemplate\n argsTemplate: *LongIsNegativeArgsTemplate\n negate:\n <<: *__func\n id: \"negate\"\n type: \"Long\"\n template: *LongNegateTemplate\n argsTemplate: *LongNegateArgsTemplate\n not:\n <<: *__func\n id: \"not\"\n type: \"Long\"\n template: *LongNotTemplate\n argsTemplate: *LongNotArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongNotEqualsTemplate\n argsTemplate: *LongNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanTemplate\n argsTemplate: *LongGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongGreaterThanOrEqualTemplate\n argsTemplate: *LongGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanTemplate\n argsTemplate: *LongLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Long\" ]\n type: *BoolType\n template: *LongLessThanOrEqualTemplate\n argsTemplate: *LongLessThanOrEqualArgsTemplate\n add:\n <<: *__func\n id: \"add\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAddTemplate\n argsTemplate: *LongAddArgsTemplate\n subtract:\n <<: *__func\n id: \"subtract\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongSubtractTemplate\n argsTemplate: *LongSubtractArgsTemplate\n multiply:\n <<: *__func\n id: \"multiply\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongMultiplyTemplate\n argsTemplate: *LongMultiplyArgsTemplate\n div:\n <<: *__func\n id: \"div\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongDivTemplate\n argsTemplate: *LongDivArgsTemplate\n modulo:\n <<: *__func\n id: \"modulo\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongModuloTemplate\n argsTemplate: *LongModuloArgsTemplate\n and:\n <<: *__func\n id: \"and\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongAndTemplate\n argsTemplate: *LongAndArgsTemplate\n or:\n <<: *__func\n id: \"or\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongOrTemplate\n argsTemplate: *LongOrArgsTemplate\n xor:\n <<: *__func\n id: \"xor\"\n args:\n - [ \"Long\" ]\n type: \"Long\"\n template: *LongXorTemplate\n argsTemplate: *LongXorArgsTemplate\n shiftLeft:\n <<: *__func\n id: \"shiftLeft\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftLeftTemplate\n argsTemplate: *LongShiftLeftArgsTemplate\n shiftRight:\n <<: *__func\n id: \"shiftRight\"\n args:\n - [ *IntegerType ]\n type: \"Long\"\n template: *LongShiftRightTemplate\n argsTemplate: *LongShiftRightArgsTemplate\n MinKeyType: &MinKeyType\n <<: *__type\n id: \"MinKey\"\n code: 107\n type: *ObjectType\n MaxKeyType: &MaxKeyType\n <<: *__type\n id: \"MaxKey\"\n code: 108\n type: *ObjectType\n Timestamp: &TimestampType\n <<: *__type\n id: \"Timestamp\"\n code: 110\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *TimestampToStringTemplate\n argsTemplate: *TimestampToStringArgsTemplate\n equals:\n <<: *__func\n id: \"equals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampEqualsTemplate\n argsTemplate: *TimestampEqualsArgsTemplate\n getLowBits:\n <<: *__func\n id: \"getLowBits\"\n type: *IntegerType\n template: *TimestampGetLowBitsTemplate\n argsTemplate: *TimestampGetLowBitsArgsTemplate\n getHighBits:\n <<: *__func\n id: \"getHighBits\"\n type: *IntegerType\n template: *TimestampGetHighBitsTemplate\n argsTemplate: *TimestampGetHighBitsArgsTemplate\n compare:\n <<: *__func\n id: \"compare\"\n args:\n - [ \"Timestamp\" ]\n type: *StringType\n template: *TimestampCompareTemplate\n argsTemplate: *TimestampCompareArgsTemplate\n notEquals:\n <<: *__func\n id: \"notEquals\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampNotEqualsTemplate\n argsTemplate: *TimestampNotEqualsArgsTemplate\n greaterThan:\n <<: *__func\n id: \"greaterThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanTemplate\n argsTemplate: *TimestampGreaterThanArgsTemplate\n greaterThanOrEqual:\n <<: *__func\n id: \"greaterThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampGreaterThanOrEqualTemplate\n argsTemplate: *TimestampGreaterThanOrEqualArgsTemplate\n lessThan:\n <<: *__func\n id: \"lessThan\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanTemplate\n argsTemplate: *TimestampLessThanArgsTemplate\n lessThanOrEqual:\n <<: *__func\n id: \"lessThanOrEqual\"\n args:\n - [ \"Timestamp\" ]\n type: *BoolType\n template: *TimestampLessThanOrEqualTemplate\n argsTemplate: *TimestampLessThanOrEqualArgsTemplate\n BSONSymbol: &SymbolType\n <<: *__type\n id: \"BSONSymbol\"\n code: 111\n type: *ObjectType\n attr:\n valueOf:\n <<: *__func\n id: \"valueOf\"\n type: *StringType\n template: *SymbolValueOfTemplate\n argsTemplate: *SymbolValueOfArgsTemplate\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *SymbolToStringTemplate\n argsTemplate: *SymbolToStringArgsTemplate\n inspect:\n <<: *__func\n id: \"inspect\"\n type: *StringType\n template: *SymbolInspectTemplate\n argsTemplate: *SymbolInspectArgsTemplate\n Double: &DoubleType\n <<: *__type\n id: \"Double\"\n code: 104\n type: *ObjectType\n attr: {}\n Decimal128: &Decimal128Type\n <<: *__type\n id: \"Decimal128\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n NumberDecimal: &NumberDecimalType\n <<: *__type\n id: \"NumberDecimal\"\n code: 112\n type: *ObjectType\n attr:\n toString:\n <<: *__func\n id: \"toString\"\n type: *StringType\n template: *Decimal128ToStringTemplate\n argsTemplate: *Decimal128ToStringArgsTemplate\n\n\n SUBTYPE_DEFAULT:\n id: \"SUBTYPE_DEFAULT\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeDefaultTemplate\n SUBTYPE_FUNCTION:\n id: \"SUBTYPE_FUNCTION\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeFunctionTemplate\n SUBTYPE_BYTE_ARRAY:\n id: \"SUBTYPE_BYTE_ARRAY\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeByteArrayTemplate\n SUBTYPE_UUID_OLD:\n id: \"SUBTYPE_UUID_OLD\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidOldTemplate\n SUBTYPE_UUID:\n id: \"SUBTYPE_UUID\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUuidTemplate\n SUBTYPE_MD5:\n id: \"SUBTYPE_MD5\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeMd5Template\n SUBTYPE_USER_DEFINED:\n id: \"SUBTYPE_USER_DEFINED\"\n callable: *var\n args: null\n code: 113\n type: *IntegerType\n template: *BinarySymbolSubtypeUserDefinedTemplate\n BSONRegExpType: &BSONRegExpType\n <<: *__type\n id: \"BSONRegExp\"\n code: 109\n type: *ObjectType\nNativeTypes:\n Date: &DateType\n <<: *__type\n id: \"Date\"\n code: 200\n type: *ObjectType\n attr: {} # TODO: no built-in date methods added yet\n RegExp: &RegExpType\n <<: *__type\n id: \"RegExp\"\n code: 8\n type: *ObjectType\n attr: {}\n\n\nBsonSymbols:\n Code: &CodeSymbol\n id: \"Code\"\n code: 100\n callable: *constructor\n args:\n - [ *StringType, null ]\n - [ *ObjectType, null ]\n type: *CodeType\n attr: {}\n template: *CodeSymbolTemplate\n argsTemplate: *CodeSymbolArgsTemplate\n ObjectId: &ObjectIdSymbol\n id: \"ObjectId\"\n code: 101\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *ObjectIdType\n attr:\n createFromHexString:\n <<: *__func\n id: \"createFromHexString\"\n args:\n - [ *StringType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromHexStringTemplate\n argsTemplate: *ObjectIdCreateFromHexStringArgsTemplate\n createFromTime:\n <<: *__func\n id: \"ObjectIdCreateFromTime\"\n args:\n - [ *NumericType, *DateType ]\n type: *ObjectIdType\n template: *ObjectIdCreateFromTimeTemplate\n argsTemplate: *ObjectIdCreateFromTimeArgsTemplate\n isValid:\n <<: *__func\n id: \"isValid\"\n args:\n - [ *StringType ]\n type: *BoolType\n template: *ObjectIdIsValidTemplate\n argsTemplate: *ObjectIdIsValidArgsTemplate\n template: *ObjectIdSymbolTemplate\n argsTemplate: *ObjectIdSymbolArgsTemplate\n BinData: &BinarySymbol\n id: \"BinData\"\n code: 102\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *StringType ]\n type: *BinaryType\n attr: {}\n template: *BinarySymbolTemplate\n argsTemplate: *BinarySymbolArgsTemplate\n DBRef:\n id: \"DBRef\"\n code: 103\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *ObjectIdType ]\n - [ *StringType, null ]\n type: *DBRefType\n attr: {}\n template: *DBRefSymbolTemplate\n argsTemplate: *DBRefSymbolArgsTemplate\n NumberInt:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType, null ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n NumberLong:\n id: \"NumberLong\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n MinKey:\n id: \"MinKey\"\n code: 107\n callable: *constructor\n args: []\n type: *MinKeyType\n attr: {}\n template: *MinKeySymbolTemplate\n argsTemplate: *MinKeySymbolArgsTemplate\n MaxKey:\n id: \"MaxKey\"\n code: 108\n callable: *constructor\n args: []\n type: *MaxKeyType\n attr: {}\n template: *MaxKeySymbolTemplate\n argsTemplate: *MaxKeySymbolArgsTemplate\n Timestamp:\n id: \"Timestamp\"\n code: 110\n callable: *constructor\n args:\n - [ *IntegerType, null ]\n - [ *IntegerType, null ]\n type: *TimestampType\n attr: {}\n template: *TimestampSymbolTemplate\n argsTemplate: *TimestampSymbolArgsTemplate\n Symbol:\n id: \"Symbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n NumberDecimal:\n id: \"NumberDecimal\"\n code: 112\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n BSONRegExp:\n id: \"BSONRegExp\"\n code: 109\n callable: *constructor\n args:\n - [ *StringType ]\n - [ *StringType, null ]\n type: *BSONRegExpType\n attr: {}\n template: *BSONRegExpSymbolTemplate\n argsTemplate: *BSONRegExpSymbolArgsTemplate\n BSONSymbol:\n id: \"BSONSymbol\"\n code: 111\n callable: *constructor\n args:\n - [ *StringType ]\n type: *SymbolType\n attr: {}\n template: *SymbolSymbolTemplate\n argsTemplate: *SymbolSymbolArgsTemplate\n Decimal128:\n id: \"Decimal128\"\n code: 112\n callable: *constructor\n args:\n - [ *ObjectType ]\n type: *Decimal128Type\n attr:\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n type: *Decimal128Type\n attr: {}\n template: *Decimal128SymbolFromStringTemplate\n argsTemplate: *Decimal128SymbolFromStringArgsTemplate\n template: *Decimal128SymbolTemplate\n argsTemplate: *Decimal128SymbolArgsTemplate\n Double:\n id: \"Double\"\n code: 104\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *DoubleType\n attr: {}\n template: *DoubleSymbolTemplate\n argsTemplate: *DoubleSymbolArgsTemplate\n Int32:\n id: \"Int32\"\n code: 105\n callable: *constructor\n args:\n - [ *NumericType, *StringType ]\n type: *Int32Type\n attr: {}\n template: *Int32SymbolTemplate\n argsTemplate: *Int32SymbolArgsTemplate\n Long:\n id: \"Long\"\n code: 106\n callable: *constructor\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr:\n MAX_VALUE:\n id: \"MAX_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMaxTemplate\n argsTemplate: *LongSymbolMaxArgsTemplate\n MIN_VALUE:\n id: \"MIN_VALUE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolMinTemplate\n argsTemplate: *LongSymbolMinArgsTemplate\n ZERO:\n id: \"ZERO\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolZeroTemplate\n argsTemplate: *LongSymbolZeroArgsTemplate\n ONE:\n id: \"ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolOneTemplate\n argsTemplate: *LongSymbolOneArgsTemplate\n NEG_ONE:\n id: \"NEG_ONE\"\n callable: *var\n args: null\n type: *LongType\n attr: {}\n template: *LongSymbolNegOneTemplate\n argsTemplate: *LongSymbolNegOneArgsTemplate\n fromBits:\n id: \"LongfromBits\" # Needs process method\n callable: *func\n args:\n - [ *IntegerType ]\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromBitsTemplate\n argsTemplate: *LongSymbolFromBitsArgsTemplate\n fromInt:\n id: \"fromInt\"\n callable: *func\n args:\n - [ *IntegerType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromIntTemplate\n argsTemplate: *LongSymbolFromIntArgsTemplate\n fromNumber:\n id: \"fromNumber\"\n callable: *func\n args:\n - [ *NumericType ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromNumberTemplate\n argsTemplate: *LongSymbolFromNumberArgsTemplate\n fromString:\n id: \"fromString\"\n callable: *func\n args:\n - [ *StringType ]\n - [ *IntegerType, null ]\n type: *LongType\n attr: {}\n template: *LongSymbolFromStringTemplate\n argsTemplate: *LongSymbolFromStringArgsTemplate\n template: *LongSymbolTemplate\n argsTemplate: *LongSymbolArgsTemplate\n\nNativeSymbols:\n Number:\n id: \"Number\"\n code: 2\n callable: *constructor\n args:\n - [ *IntegerType, *StringType, null ]\n type: *NumericType\n attr: {} # TODO: no built-in number funcs added yet\n template: *NumberSymbolTemplate\n argsTemplate: *NumberSymbolArgsTemplate\n Date: # Needs emit method\n id: \"Date\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n - [ *NumericType, null ]\n type: *DateType\n attr: # TODO: add more date funcs?\n now:\n id: \"now\"\n code: 200.1\n callable: *func\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n ISODate: # Needs emit method\n id: \"ISODate\"\n code: 200\n callable: *constructor\n args:\n - [ *StringType, null ]\n type: *DateType\n attr:\n now:\n id: \"now\"\n callable: *constructor\n args: []\n type: *DateType\n attr: {}\n template: *DateSymbolNowTemplate\n argsTemplate: *DateSymbolNowArgsTemplate\n template: *DateSymbolTemplate\n argsTemplate: *DateSymbolArgsTemplate\n RegExp: # Needs process method\n id: \"RegExp\"\n code: 8\n callable: *constructor\n args:\n - [ *StringType, *RegexType ]\n - [ *StringType, null ]\n type: *RegExpType\n attr: {} # TODO: no built-in regex funcs added yet\n template: *RegExpSymbolTemplate\n argsTemplate: *RegExpSymbolArgsTemplate\n\n"; diff --git a/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx b/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx index fa7a62f77e9..6bef5e47670 100644 --- a/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx +++ b/packages/compass-data-modeling/src/services/data-model-storage-electron.tsx @@ -12,10 +12,13 @@ class DataModelStorageElectron implements DataModelStorage { typeof MongoDBDataModelDescriptionSchema >; constructor(basePath?: string) { - this.userData = new FileUserData(MongoDBDataModelDescriptionSchema, { - subdir: 'DataModelDescriptions', - basePath, - }); + this.userData = new FileUserData( + MongoDBDataModelDescriptionSchema, + 'DataModelDescription', + { + basePath, + } + ); } save(description: MongoDBDataModelDescription) { return this.userData.write(description.id, description); diff --git a/packages/compass-preferences-model/src/preferences-persistent-storage.ts b/packages/compass-preferences-model/src/preferences-persistent-storage.ts index 2a66dee37d5..6a29259d4ce 100644 --- a/packages/compass-preferences-model/src/preferences-persistent-storage.ts +++ b/packages/compass-preferences-model/src/preferences-persistent-storage.ts @@ -25,10 +25,13 @@ export class PersistentStorage implements PreferencesStorage { private safeStorage?: PreferencesSafeStorage; constructor(basePath?: string, safeStorage?: PreferencesSafeStorage) { - this.userData = new FileUserData(getPreferencesValidator(), { - subdir: 'AppPreferences', - basePath, - }); + this.userData = new FileUserData( + getPreferencesValidator(), + 'AppPreferences', + { + basePath, + } + ); this.safeStorage = safeStorage; } diff --git a/packages/compass-preferences-model/src/user-storage.ts b/packages/compass-preferences-model/src/user-storage.ts index fbaed7f7b27..26224c04c3f 100644 --- a/packages/compass-preferences-model/src/user-storage.ts +++ b/packages/compass-preferences-model/src/user-storage.ts @@ -26,8 +26,7 @@ export interface UserStorage { export class UserStorageImpl implements UserStorage { private readonly userData: FileUserData; constructor(basePath?: string) { - this.userData = new FileUserData(UserSchema, { - subdir: 'Users', + this.userData = new FileUserData(UserSchema, 'Users', { basePath, }); } diff --git a/packages/compass-shell/src/modules/history-storage.ts b/packages/compass-shell/src/modules/history-storage.ts index 5f1cab73a04..7af6c4e386a 100644 --- a/packages/compass-shell/src/modules/history-storage.ts +++ b/packages/compass-shell/src/modules/history-storage.ts @@ -6,9 +6,8 @@ export class HistoryStorage { userData; constructor(basePath?: string) { - this.userData = new FileUserData(z.string().array(), { + this.userData = new FileUserData(z.string().array(), getAppName() ?? '', { // Todo: https://jira.mongodb.org/browse/COMPASS-7080 - subdir: getAppName() ?? '', basePath, }); } diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index 3aab9ca8afa..971262ce6e5 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -34,7 +34,7 @@ const getTestSchema = ( }; const defaultValues = () => getTestSchema().parse({}); -const subdir = 'test-dir'; +const dataType = 'RecentQueries'; describe('user-data', function () { let tmpDir: string; @@ -53,29 +53,19 @@ describe('user-data', function () { > = {}, validatorOpts: ValidatorOptions = {} ) => { - return new FileUserData(getTestSchema(validatorOpts), { - subdir, + return new FileUserData(getTestSchema(validatorOpts), dataType, { basePath: tmpDir, ...userDataOpts, }); }; const writeFileToStorage = async (filepath: string, contents: string) => { - const absolutePath = path.join(tmpDir, subdir, filepath); + const absolutePath = path.join(tmpDir, dataType, filepath); await fs.mkdir(path.dirname(absolutePath), { recursive: true }); await fs.writeFile(absolutePath, contents, 'utf-8'); }; context('UserData.readAll', function () { - it('does not throw if the subdir does not exist and returns an empty list', async function () { - const userData = getUserData({ - subdir: 'something/non-existant', - }); - const result = await userData.readAll(); - expect(result.data).to.have.lengthOf(0); - expect(result.errors).to.have.lengthOf(0); - }); - it('reads all files from the folder with defaults', async function () { await Promise.all( [ @@ -330,14 +320,6 @@ describe('user-data', function () { }); context('UserData.write', function () { - it('does not throw if the subdir does not exist', async function () { - const userData = getUserData({ - subdir: 'something/non-existant', - }); - const isWritten = await userData.write('data', { w: 1 }); - expect(isWritten).to.be.true; - }); - it('writes file to the storage with content', async function () { const userData = getUserData(); await userData.write('data', { name: 'VSCode' }); @@ -348,19 +330,11 @@ describe('user-data', function () { }); context('UserData.delete', function () { - it('does not throw if the subdir does not exist', async function () { - const userData = getUserData({ - subdir: 'something/non-existant', - }); - const isDeleted = await userData.delete('data.json'); - expect(isDeleted).to.be.false; - }); - it('deletes a file', async function () { const userData = getUserData(); const fileId = 'data'; - const absolutePath = path.join(tmpDir, subdir, `${fileId}.json`); + const absolutePath = path.join(tmpDir, dataType, `${fileId}.json`); await userData.write(fileId, { name: 'Compass' }); @@ -394,7 +368,7 @@ describe('user-data', function () { await userData.write('serialized', data); - const absolutePath = path.join(tmpDir, subdir, 'serialized.json'); + const absolutePath = path.join(tmpDir, dataType, 'serialized.json'); const writtenData = JSON.parse( (await fs.readFile(absolutePath)).toString() @@ -443,9 +417,9 @@ describe('AtlasUserData', function () { orgId = 'test-org', projectId = 'test-proj', type: - | 'recentQueries' - | 'favoriteQueries' - | 'favoriteAggregations' = 'favoriteQueries' + | 'RecentQueries' + | 'FavoriteQueries' + | 'SavedPipelines' = 'FavoriteQueries' ) => { return new AtlasUserData( getTestSchema(validatorOpts), @@ -471,7 +445,7 @@ describe('AtlasUserData', function () { it('writes data successfully', async function () { authenticatedFetchStub.resolves(mockResponse({})); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -482,7 +456,7 @@ describe('AtlasUserData', function () { const [url, options] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); expect(options.method).to.equal('POST'); expect(options.headers['Content-Type']).to.equal('application/json'); @@ -499,7 +473,7 @@ describe('AtlasUserData', function () { it('returns false when response is not ok', async function () { authenticatedFetchStub.resolves(mockResponse({}, false, 500)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -511,7 +485,7 @@ describe('AtlasUserData', function () { it('validator removes unknown props', async function () { authenticatedFetchStub.resolves(mockResponse({})); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -527,12 +501,12 @@ describe('AtlasUserData', function () { it('uses custom serializer when provided', async function () { authenticatedFetchStub.resolves(mockResponse({})); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = new AtlasUserData( getTestSchema(), - 'favoriteQueries', + 'FavoriteQueries', 'test-org', 'test-proj', getResourceUrlStub, @@ -554,7 +528,7 @@ describe('AtlasUserData', function () { it('deletes data successfully', async function () { authenticatedFetchStub.resolves(mockResponse({})); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj/test-id' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj/test-id' ); const userData = getAtlasUserData(); @@ -565,7 +539,7 @@ describe('AtlasUserData', function () { const [url, options] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj/test-id' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj/test-id' ); expect(options.method).to.equal('DELETE'); }); @@ -573,7 +547,7 @@ describe('AtlasUserData', function () { it('returns false when response is not ok', async function () { authenticatedFetchStub.resolves(mockResponse({}, false, 404)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -591,7 +565,7 @@ describe('AtlasUserData', function () { ]; authenticatedFetchStub.resolves(mockResponse(responseData)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -619,7 +593,7 @@ describe('AtlasUserData', function () { expect(authenticatedFetchStub).to.have.been.calledOnce; const [url, options] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); expect(options.method).to.equal('GET'); }); @@ -627,7 +601,7 @@ describe('AtlasUserData', function () { it('handles empty response', async function () { authenticatedFetchStub.resolves(mockResponse([])); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -640,7 +614,7 @@ describe('AtlasUserData', function () { it('handles non-array response', async function () { authenticatedFetchStub.resolves(mockResponse({ notAnArray: true })); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -653,7 +627,7 @@ describe('AtlasUserData', function () { it('handles errors gracefully', async function () { authenticatedFetchStub.rejects(new Error('Unknown error')); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -667,7 +641,7 @@ describe('AtlasUserData', function () { it('handles non-ok response gracefully', async function () { authenticatedFetchStub.resolves(mockResponse({}, false, 500)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -682,12 +656,12 @@ describe('AtlasUserData', function () { const responseData = [{ data: 'custom:{"name":"Custom"}' }]; authenticatedFetchStub.resolves(mockResponse(responseData)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = new AtlasUserData( getTestSchema(), - 'favoriteQueries', + 'FavoriteQueries', 'test-org', 'test-proj', getResourceUrlStub, @@ -723,7 +697,7 @@ describe('AtlasUserData', function () { ]; authenticatedFetchStub.resolves(mockResponse(responseData)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -744,7 +718,7 @@ describe('AtlasUserData', function () { const putResponse = { name: 'Updated Name', hasDarkMode: false }; authenticatedFetchStub.resolves(mockResponse(putResponse)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj/test-id' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj/test-id' ); const userData = getAtlasUserData(); @@ -758,7 +732,7 @@ describe('AtlasUserData', function () { expect(authenticatedFetchStub).to.have.been.calledOnce; const [url, options] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj/test-id' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj/test-id' ); expect(options.method).to.equal('PUT'); expect(options.headers['Content-Type']).to.equal('application/json'); @@ -767,7 +741,7 @@ describe('AtlasUserData', function () { it('returns false when response is not ok', async function () { authenticatedFetchStub.resolves(mockResponse({}, false, 400)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = getAtlasUserData(); @@ -782,12 +756,12 @@ describe('AtlasUserData', function () { const putResponse = { name: 'Updated' }; authenticatedFetchStub.resolves(mockResponse(putResponse)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/test-org/test-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' ); const userData = new AtlasUserData( getTestSchema(), - 'favoriteQueries', + 'FavoriteQueries', 'test-org', 'test-proj', getResourceUrlStub, @@ -808,7 +782,7 @@ describe('AtlasUserData', function () { it('constructs URL correctly for write operation', async function () { authenticatedFetchStub.resolves(mockResponse({})); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/custom-org/custom-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/custom-org/custom-proj' ); const userData = getAtlasUserData({}, 'custom-org', 'custom-proj'); @@ -816,14 +790,14 @@ describe('AtlasUserData', function () { const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/custom-org/custom-proj' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/custom-org/custom-proj' ); }); it('constructs URL correctly for delete operation', async function () { authenticatedFetchStub.resolves(mockResponse({})); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/org123/proj456/item789' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org123/proj456/item789' ); const userData = getAtlasUserData({}, 'org123', 'proj456'); @@ -831,14 +805,14 @@ describe('AtlasUserData', function () { const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/org123/proj456/item789' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org123/proj456/item789' ); }); it('constructs URL correctly for read operation', async function () { authenticatedFetchStub.resolves(mockResponse({})); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/org456/proj123' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org456/proj123' ); const userData = getAtlasUserData({}, 'org456', 'proj123'); @@ -847,7 +821,7 @@ describe('AtlasUserData', function () { const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/org456/proj123' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org456/proj123' ); }); @@ -855,7 +829,7 @@ describe('AtlasUserData', function () { const putResponse = { data: { name: 'Updated' } }; authenticatedFetchStub.resolves(mockResponse(putResponse)); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/org123/proj456/item789' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org123/proj456/item789' ); const userData = getAtlasUserData({}, 'org123', 'proj456'); @@ -863,27 +837,27 @@ describe('AtlasUserData', function () { const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud.mongodb.com/favoriteQueries/org123/proj456/item789' + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org123/proj456/item789' ); }); it('constructs URL correctly for different types', async function () { authenticatedFetchStub.resolves(mockResponse({})); getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/recentQueries/org123/proj456' + 'cluster-connection.cloud.mongodb.com/RecentQueries/org123/proj456' ); const userData = getAtlasUserData( {}, 'org123', 'proj456', - 'recentQueries' + 'RecentQueries' ); await userData.write('item789', { name: 'Recent Item' }); const [url] = authenticatedFetchStub.firstCall.args; expect(url).to.equal( - 'cluster-connection.cloud.mongodb.com/recentQueries/org123/proj456' + 'cluster-connection.cloud.mongodb.com/RecentQueries/org123/proj456' ); }); }); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index fcffd95af22..e9dfa21342b 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -11,9 +11,13 @@ const { log, mongoLogId } = createLogger('COMPASS-USER-STORAGE'); type SerializeContent = (content: I) => string; type DeserializeContent = (content: string) => unknown; type GetFileName = (id: string) => string; +type GetResourceUrl = (path?: string) => Promise; +type AuthenticatedFetch = ( + url: RequestInfo | URL, + options?: RequestInit +) => Promise; export type FileUserDataOptions = { - subdir: string; basePath?: string; serialize?: SerializeContent; deserialize?: DeserializeContent; @@ -70,10 +74,12 @@ export interface ReadAllWithStatsResult { export abstract class IUserData { protected readonly validator: T; + protected readonly dataType: string; protected readonly serialize: SerializeContent>; protected readonly deserialize: DeserializeContent; constructor( validator: T, + dataType: string, { serialize = (content: z.input) => JSON.stringify(content, null, 2), deserialize = JSON.parse, @@ -83,6 +89,7 @@ export abstract class IUserData { } = {} ) { this.validator = validator; + this.dataType = dataType; this.serialize = serialize; this.deserialize = deserialize; } @@ -97,23 +104,21 @@ export abstract class IUserData { } export class FileUserData extends IUserData { - private readonly subdir: string; private readonly basePath?: string; private readonly getFileName: GetFileName; protected readonly semaphore = new Semaphore(100); constructor( validator: T, + dataType: string, { - subdir, basePath, serialize, deserialize, getFileName = (id) => `${id}.json`, }: FileUserDataOptions> ) { - super(validator, { serialize, deserialize }); - this.subdir = subdir; + super(validator, dataType, { serialize, deserialize }); this.basePath = basePath; this.getFileName = getFileName; } @@ -121,7 +126,7 @@ export class FileUserData extends IUserData { private async getEnsuredBasePath(): Promise { const basepath = this.basePath ? this.basePath : getStoragePath(); - const root = path.join(basepath, this.subdir); + const root = path.join(basepath, this.dataType); await fs.mkdir(root, { recursive: true }); @@ -343,28 +348,20 @@ export class AtlasUserData extends IUserData { private readonly getResourceUrl; private orgId: string = ''; private projectId: string = ''; - private readonly type: - | 'recentQueries' - | 'favoriteQueries' - | 'favoriteAggregations'; constructor( validator: T, - type: 'recentQueries' | 'favoriteQueries' | 'favoriteAggregations', + dataType: string, orgId: string, projectId: string, - getResourceUrl: (path?: string) => Promise, - authenticatedFetch: ( - url: RequestInfo | URL, - options?: RequestInit - ) => Promise, + getResourceUrl: GetResourceUrl, + authenticatedFetch: AuthenticatedFetch, { serialize, deserialize }: AtlasUserDataOptions> ) { - super(validator, { serialize, deserialize }); + super(validator, dataType, { serialize, deserialize }); this.authenticatedFetch = authenticatedFetch; this.getResourceUrl = getResourceUrl; this.orgId = orgId; this.projectId = projectId; - this.type = type; } async write(id: string, content: z.input): Promise { @@ -373,7 +370,7 @@ export class AtlasUserData extends IUserData { const response = await this.authenticatedFetch( await this.getResourceUrl( - `${this.type}/${this.orgId}/${this.projectId}` + `${this.dataType}/${this.orgId}/${this.projectId}` ), { method: 'POST', @@ -403,7 +400,7 @@ export class AtlasUserData extends IUserData { 'Error writing data', { url: await this.getResourceUrl( - `${this.type}/${this.orgId}/${this.projectId}` + `${this.dataType}/${this.orgId}/${this.projectId}` ), error: (error as Error).message, } @@ -416,7 +413,7 @@ export class AtlasUserData extends IUserData { try { const response = await this.authenticatedFetch( await this.getResourceUrl( - `${this.type}/${this.orgId}/${this.projectId}/${id}` + `${this.dataType}/${this.orgId}/${this.projectId}/${id}` ), { method: 'DELETE', @@ -435,7 +432,7 @@ export class AtlasUserData extends IUserData { 'Error deleting data', { url: await this.getResourceUrl( - `${this.type}/${this.orgId}/${this.projectId}/${id}` + `${this.dataType}/${this.orgId}/${this.projectId}/${id}` ), error: (error as Error).message, } @@ -452,7 +449,7 @@ export class AtlasUserData extends IUserData { try { const response = await this.authenticatedFetch( await this.getResourceUrl( - `${this.type}/${this.orgId}/${this.projectId}` + `${this.dataType}/${this.orgId}/${this.projectId}` ), { method: 'GET', @@ -486,7 +483,7 @@ export class AtlasUserData extends IUserData { try { const response = await this.authenticatedFetch( await this.getResourceUrl( - `${this.type}/${this.orgId}/${this.projectId}/${id}` + `${this.dataType}/${this.orgId}/${this.projectId}/${id}` ), { method: 'PUT', @@ -509,7 +506,7 @@ export class AtlasUserData extends IUserData { 'Error updating data', { url: await this.getResourceUrl( - `${this.type}/${this.orgId}/${this.projectId}/${id}` + `${this.dataType}/${this.orgId}/${this.projectId}/${id}` ), error: (error as Error).message, } diff --git a/packages/connection-storage/src/compass-main-connection-storage.ts b/packages/connection-storage/src/compass-main-connection-storage.ts index 78f5380b735..19c9f468292 100644 --- a/packages/connection-storage/src/compass-main-connection-storage.ts +++ b/packages/connection-storage/src/compass-main-connection-storage.ts @@ -95,8 +95,7 @@ class CompassMainConnectionStorage implements ConnectionStorage { private readonly ipcMain: ConnectionStorageIPCMain, basePath?: string ) { - this.userData = new FileUserData(ConnectionSchema, { - subdir: 'Connections', + this.userData = new FileUserData(ConnectionSchema, 'Connections', { basePath, }); this.ipcMain.createHandle( diff --git a/packages/my-queries-storage/src/compass-pipeline-storage.ts b/packages/my-queries-storage/src/compass-pipeline-storage.ts index 766fc0166a0..216463a19a1 100644 --- a/packages/my-queries-storage/src/compass-pipeline-storage.ts +++ b/packages/my-queries-storage/src/compass-pipeline-storage.ts @@ -7,8 +7,7 @@ import type { PipelineStorage } from './pipeline-storage'; export class CompassPipelineStorage implements PipelineStorage { private readonly userData: FileUserData; constructor(basePath?: string) { - this.userData = new FileUserData(PipelineSchema, { - subdir: 'SavedPipelines', + this.userData = new FileUserData(PipelineSchema, 'SavedPipelines', { basePath, }); } @@ -56,7 +55,7 @@ export class CompassPipelineStorage implements PipelineStorage { : this.create(attributes)); } - private async create(data: SavedPipeline) { + async create(data: SavedPipeline) { await this.userData.write(data.id, { ...data, lastModified: Date.now(), diff --git a/packages/my-queries-storage/src/compass-query-storage.ts b/packages/my-queries-storage/src/compass-query-storage.ts index 288e84e41be..dfcfbca36c5 100644 --- a/packages/my-queries-storage/src/compass-query-storage.ts +++ b/packages/my-queries-storage/src/compass-query-storage.ts @@ -16,8 +16,7 @@ export abstract class CompassQueryStorage { protected readonly options: QueryStorageOptions ) { // TODO: logic for whether we're in compass web or compass desktop - this.userData = new FileUserData(schemaValidator, { - subdir: folder, + this.userData = new FileUserData(schemaValidator, folder, { basePath: options.basepath, serialize: (content) => EJSON.stringify(content, undefined, 2), deserialize: (content: string) => EJSON.parse(content), diff --git a/packages/my-queries-storage/src/pipeline-storage.ts b/packages/my-queries-storage/src/pipeline-storage.ts index 7924645e6fe..529652b98b1 100644 --- a/packages/my-queries-storage/src/pipeline-storage.ts +++ b/packages/my-queries-storage/src/pipeline-storage.ts @@ -6,6 +6,7 @@ export interface PipelineStorage { predicate: (arg0: SavedPipeline) => boolean ): Promise; createOrUpdate(id: string, attributes: SavedPipeline): Promise; + create(attributes: SavedPipeline): Promise; updateAttributes( id: string, attributes: Partial From 73b2bd1fe40d59dc17aabb00a196097dd3ee2c3d Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Thu, 24 Jul 2025 10:14:21 -0400 Subject: [PATCH 24/26] fix(user-data): add datatype to IUserData abstract class & tests --- .../compass-user-data/src/user-data.spec.ts | 132 ++++++++++++++---- packages/compass-user-data/src/user-data.ts | 25 +++- 2 files changed, 128 insertions(+), 29 deletions(-) diff --git a/packages/compass-user-data/src/user-data.spec.ts b/packages/compass-user-data/src/user-data.spec.ts index 971262ce6e5..6d93722fd32 100644 --- a/packages/compass-user-data/src/user-data.spec.ts +++ b/packages/compass-user-data/src/user-data.spec.ts @@ -715,11 +715,26 @@ describe('AtlasUserData', function () { context('AtlasUserData.updateAttributes', function () { it('updates data successfully', async function () { - const putResponse = { name: 'Updated Name', hasDarkMode: false }; - authenticatedFetchStub.resolves(mockResponse(putResponse)); - getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj/test-id' - ); + const getResponse = { + data: JSON.stringify({ name: 'Original Name', hasDarkMode: true }), + }; + const putResponse = {}; + + authenticatedFetchStub + .onFirstCall() + .resolves(mockResponse(getResponse)) + .onSecondCall() + .resolves(mockResponse(putResponse)); + + getResourceUrlStub + .onFirstCall() + .resolves( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' + ) + .onSecondCall() + .resolves( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj/test-id' + ); const userData = getAtlasUserData(); const result = await userData.updateAttributes('test-id', { @@ -729,20 +744,42 @@ describe('AtlasUserData', function () { expect(result).equals(true); - expect(authenticatedFetchStub).to.have.been.calledOnce; - const [url, options] = authenticatedFetchStub.firstCall.args; - expect(url).to.equal( + expect(authenticatedFetchStub).to.have.been.calledTwice; + + const [getUrl, getOptions] = authenticatedFetchStub.firstCall.args; + expect(getUrl).to.equal( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' + ); + expect(getOptions.method).to.equal('GET'); + + const [putUrl, putOptions] = authenticatedFetchStub.secondCall.args; + expect(putUrl).to.equal( 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj/test-id' ); - expect(options.method).to.equal('PUT'); - expect(options.headers['Content-Type']).to.equal('application/json'); + expect(putOptions.method).to.equal('PUT'); + expect(putOptions.headers['Content-Type']).to.equal('application/json'); }); it('returns false when response is not ok', async function () { - authenticatedFetchStub.resolves(mockResponse({}, false, 400)); - getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' - ); + const getResponse = { + data: JSON.stringify({ name: 'Original Name', hasDarkMode: true }), + }; + + authenticatedFetchStub + .onFirstCall() + .resolves(mockResponse(getResponse)) + .onSecondCall() + .resolves(mockResponse({}, false, 400)); + + getResourceUrlStub + .onFirstCall() + .resolves( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' + ) + .onSecondCall() + .resolves( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj/test-id' + ); const userData = getAtlasUserData(); @@ -753,11 +790,26 @@ describe('AtlasUserData', function () { }); it('uses custom serializer for request body', async function () { - const putResponse = { name: 'Updated' }; - authenticatedFetchStub.resolves(mockResponse(putResponse)); - getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' - ); + const getResponse = { + data: JSON.stringify({ name: 'Original Name', hasDarkMode: true }), + }; + const putResponse = {}; + + authenticatedFetchStub + .onFirstCall() + .resolves(mockResponse(getResponse)) + .onSecondCall() + .resolves(mockResponse(putResponse)); + + getResourceUrlStub + .onFirstCall() + .resolves( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj' + ) + .onSecondCall() + .resolves( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/test-org/test-proj/test-id' + ); const userData = new AtlasUserData( getTestSchema(), @@ -773,8 +825,10 @@ describe('AtlasUserData', function () { await userData.updateAttributes('test-id', { name: 'Updated' }); - const [, options] = authenticatedFetchStub.firstCall.args; - expect(options.body as string).to.equal('custom:{"name":"Updated"}'); + const [, putOptions] = authenticatedFetchStub.secondCall.args; + expect(putOptions.body as string).to.equal( + 'custom:{"name":"Updated","hasDarkMode":true,"hasWebSupport":false}' + ); }); }); @@ -826,17 +880,39 @@ describe('AtlasUserData', function () { }); it('constructs URL correctly for update operation', async function () { - const putResponse = { data: { name: 'Updated' } }; - authenticatedFetchStub.resolves(mockResponse(putResponse)); - getResourceUrlStub.resolves( - 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org123/proj456/item789' - ); + const getResponse = { + data: JSON.stringify({ name: 'Original', hasDarkMode: true }), + }; + const putResponse = {}; + + authenticatedFetchStub + .onFirstCall() + .resolves(mockResponse(getResponse)) + .onSecondCall() + .resolves(mockResponse(putResponse)); + + getResourceUrlStub + .onFirstCall() + .resolves( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org123/proj456' + ) + .onSecondCall() + .resolves( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org123/proj456/item789' + ); const userData = getAtlasUserData({}, 'org123', 'proj456'); await userData.updateAttributes('item789', { name: 'Updated' }); - const [url] = authenticatedFetchStub.firstCall.args; - expect(url).to.equal( + expect(authenticatedFetchStub).to.have.been.calledTwice; + + const [getUrl] = authenticatedFetchStub.firstCall.args; + expect(getUrl).to.equal( + 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org123/proj456' + ); + + const [putUrl] = authenticatedFetchStub.secondCall.args; + expect(putUrl).to.equal( 'cluster-connection.cloud.mongodb.com/FavoriteQueries/org123/proj456/item789' ); }); diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index e9dfa21342b..602cb7432df 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -481,6 +481,29 @@ export class AtlasUserData extends IUserData { data: Partial> ): Promise { try { + // TODO: change this depending on whether or not updateAttributes can provide all current data + const getResponse = await this.authenticatedFetch( + await this.getResourceUrl( + `${this.dataType}/${this.orgId}/${this.projectId}/${id}` + ), + { + method: 'GET', + } + ); + if (!getResponse.ok) { + throw new Error( + `Failed to fetch data: ${getResponse.status} ${getResponse.statusText}` + ); + } + const prevData = await getResponse.json(); + const validPrevData = this.validator.parse( + this.deserialize(prevData.data as string) + ); + const newData: z.input = { + ...validPrevData, + ...data, + }; + const response = await this.authenticatedFetch( await this.getResourceUrl( `${this.dataType}/${this.orgId}/${this.projectId}/${id}` @@ -490,7 +513,7 @@ export class AtlasUserData extends IUserData { headers: { 'Content-Type': 'application/json', }, - body: this.serialize(data), + body: this.serialize(newData), } ); if (!response.ok) { From df135f3c8efd2ab9e358b53f419e82b148fc5a4f Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Thu, 24 Jul 2025 12:03:38 -0400 Subject: [PATCH 25/26] fix(user-data): make create and update return type to be boolean, like queries --- packages/compass-user-data/src/user-data.ts | 56 ++++++++++++------- .../src/compass-pipeline-storage.spec.ts | 24 +++----- .../src/compass-pipeline-storage.ts | 38 +++++++------ .../src/pipeline-storage.ts | 6 +- 4 files changed, 69 insertions(+), 55 deletions(-) diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 8ea2e4c82d2..6160551e6f5 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -404,26 +404,9 @@ export class AtlasUserData extends IUserData { data: Partial> ): Promise { try { - // TODO: change this depending on whether or not updateAttributes can provide all current data - const getResponse = await this.authenticatedFetch( - await this.getResourceUrl( - `${this.dataType}/${this.orgId}/${this.projectId}/${id}` - ), - { - method: 'GET', - } - ); - if (!getResponse.ok) { - throw new Error( - `Failed to fetch data: ${getResponse.status} ${getResponse.statusText}` - ); - } - const prevData = await getResponse.json(); - const validPrevData = this.validator.parse( - this.deserialize(prevData.data as string) - ); + const prevData = await this.readOne(id); const newData: z.input = { - ...validPrevData, + ...prevData, ...data, }; @@ -460,4 +443,39 @@ export class AtlasUserData extends IUserData { return false; } } + + // TODO: change this depending on whether or not updateAttributes can provide all current data + async readOne(id: string): Promise> { + try { + const getResponse = await this.authenticatedFetch( + await this.getResourceUrl( + `${this.dataType}/${this.orgId}/${this.projectId}/${id}` + ), + { + method: 'GET', + } + ); + if (!getResponse.ok) { + throw new Error( + `Failed to fetch data: ${getResponse.status} ${getResponse.statusText}` + ); + } + const json = await getResponse.json(); + const data = this.validator.parse(this.deserialize(json.data as string)); + return data; + } catch { + log.error( + mongoLogId(1_001_000_365), + 'Atlas Backend', + 'Error reading data', + { + url: await this.getResourceUrl( + `${this.dataType}/${this.orgId}/${this.projectId}/${id}` + ), + error: (error as Error).message, + } + ); + return null; + } + } } diff --git a/packages/my-queries-storage/src/compass-pipeline-storage.spec.ts b/packages/my-queries-storage/src/compass-pipeline-storage.spec.ts index a1ae70727ef..26329ab6cf3 100644 --- a/packages/my-queries-storage/src/compass-pipeline-storage.spec.ts +++ b/packages/my-queries-storage/src/compass-pipeline-storage.spec.ts @@ -87,14 +87,12 @@ describe('CompassPipelineStorage', function () { expect((e as any).code).to.equal('ENOENT'); } - const pipeline = await pipelineStorage.createOrUpdate(data.id, data); + const result = await pipelineStorage.createOrUpdate(data.id, data); // Verify the file exists await fs.access(await getEnsuredFilePath(tmpDir, data.id)); - expect(pipeline.id).to.equal(data.id); - expect(pipeline.name).to.equal(data.name); - expect(pipeline.pipelineText).to.equal(data.pipelineText); + expect(result).to.be.true; }); it('createOrUpdate - updates a pipeline if it exists', async function () { @@ -108,14 +106,12 @@ describe('CompassPipelineStorage', function () { await createPipeline(tmpDir, data); await fs.access(await getEnsuredFilePath(tmpDir, data.id)); - const pipeline = await pipelineStorage.createOrUpdate(data.id, { + const result = await pipelineStorage.createOrUpdate(data.id, { ...data, name: 'modified listings', }); - expect(pipeline.id).to.equal(data.id); - expect(pipeline.name).to.equal('modified listings'); - expect(pipeline.pipelineText).to.equal(data.pipelineText); + expect(result).to.be.true; }); it('updateAttributes - updates a pipeline if it exists', async function () { @@ -136,17 +132,13 @@ describe('CompassPipelineStorage', function () { expect(restOfAggregation).to.deep.equal(data); } // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { lastModified, pipelineText, ...updatedAggregation } = - await pipelineStorage.updateAttributes(data.id, { - name: 'updated', - namespace: 'airbnb.users', - }); - - expect(updatedAggregation, 'returns updated pipeline').to.deep.equal({ - ...data, + const result = await pipelineStorage.updateAttributes(data.id, { name: 'updated', + namespace: 'airbnb.users', }); + expect(result).to.be.true; + { const aggregations = await pipelineStorage.loadAll(); expect(aggregations).to.have.length(1); diff --git a/packages/my-queries-storage/src/compass-pipeline-storage.ts b/packages/my-queries-storage/src/compass-pipeline-storage.ts index 624b6c4094e..8c42eeb722b 100644 --- a/packages/my-queries-storage/src/compass-pipeline-storage.ts +++ b/packages/my-queries-storage/src/compass-pipeline-storage.ts @@ -27,10 +27,6 @@ export class CompassPipelineStorage implements PipelineStorage { return this.loadAll().then((pipelines) => pipelines.filter(predicate)); } - private async loadOne(id: string): Promise { - return await this.userData.readOne(id); - } - async createOrUpdate( id: string, attributes: Omit @@ -41,24 +37,32 @@ export class CompassPipelineStorage implements PipelineStorage { : this.create(attributes)); } - async create(data: Omit) { - await this.userData.write(data.id, { - ...data, - lastModified: Date.now(), - }); - return await this.loadOne(data.id); + async create(data: Omit): Promise { + try { + await this.userData.write(data.id, { + ...data, + lastModified: Date.now(), + }); + return true; + } catch { + return false; + } } async updateAttributes( id: string, attributes: Partial - ): Promise { - await this.userData.write(id, { - ...(await this.loadOne(id)), - ...attributes, - lastModified: Date.now(), - }); - return await this.loadOne(id); + ): Promise { + try { + await this.userData.write(id, { + ...(await this.userData.readOne(id)), + ...attributes, + lastModified: Date.now(), + }); + return true; + } catch { + return false; + } } async delete(id: string) { diff --git a/packages/my-queries-storage/src/pipeline-storage.ts b/packages/my-queries-storage/src/pipeline-storage.ts index 529652b98b1..3464f1bd87e 100644 --- a/packages/my-queries-storage/src/pipeline-storage.ts +++ b/packages/my-queries-storage/src/pipeline-storage.ts @@ -5,11 +5,11 @@ export interface PipelineStorage { loadMany( predicate: (arg0: SavedPipeline) => boolean ): Promise; - createOrUpdate(id: string, attributes: SavedPipeline): Promise; - create(attributes: SavedPipeline): Promise; + createOrUpdate(id: string, attributes: SavedPipeline): Promise; + create(attributes: SavedPipeline): Promise; updateAttributes( id: string, attributes: Partial - ): Promise; + ): Promise; delete(id: string): Promise; } From f6efcd6707f8fc374c5acfae7ca29ab4135c756c Mon Sep 17 00:00:00 2001 From: Moses Yuan Qing Yang Date: Thu, 24 Jul 2025 12:38:49 -0400 Subject: [PATCH 26/26] fix(compass-aggregations): fix method typing --- packages/compass-user-data/src/user-data.ts | 2 +- packages/my-queries-storage/src/pipeline-storage.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/compass-user-data/src/user-data.ts b/packages/compass-user-data/src/user-data.ts index 6160551e6f5..11de8a1230c 100644 --- a/packages/compass-user-data/src/user-data.ts +++ b/packages/compass-user-data/src/user-data.ts @@ -463,7 +463,7 @@ export class AtlasUserData extends IUserData { const json = await getResponse.json(); const data = this.validator.parse(this.deserialize(json.data as string)); return data; - } catch { + } catch (error) { log.error( mongoLogId(1_001_000_365), 'Atlas Backend', diff --git a/packages/my-queries-storage/src/pipeline-storage.ts b/packages/my-queries-storage/src/pipeline-storage.ts index 3464f1bd87e..ae10ed65ea7 100644 --- a/packages/my-queries-storage/src/pipeline-storage.ts +++ b/packages/my-queries-storage/src/pipeline-storage.ts @@ -5,8 +5,11 @@ export interface PipelineStorage { loadMany( predicate: (arg0: SavedPipeline) => boolean ): Promise; - createOrUpdate(id: string, attributes: SavedPipeline): Promise; - create(attributes: SavedPipeline): Promise; + createOrUpdate( + id: string, + attributes: Omit + ): Promise; + create(attributes: Omit): Promise; updateAttributes( id: string, attributes: Partial