diff --git a/packages/mql-typescript/tests/real.js b/packages/mql-typescript/tests/real.js new file mode 100644 index 00000000..8401f894 --- /dev/null +++ b/packages/mql-typescript/tests/real.js @@ -0,0 +1,186 @@ +'use strict'; +var __awaiter = + (this && this.__awaiter) || + function (thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P + ? value + : new P(function (resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator['throw'](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done + ? resolve(result.value) + : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; +var __generator = + (this && this.__generator) || + function (thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [], + }, + f, + y, + t, + g = Object.create( + (typeof Iterator === 'function' ? Iterator : Object).prototype, + ); + return ( + (g.next = verb(0)), + (g['throw'] = verb(1)), + (g['return'] = verb(2)), + typeof Symbol === 'function' && + (g[Symbol.iterator] = function () { + return this; + }), + g + ); + function verb(n) { + return function (v) { + return step([n, v]); + }; + } + function step(op) { + if (f) throw new TypeError('Generator is already executing.'); + while ((g && ((g = 0), op[0] && (_ = 0)), _)) + try { + if ( + ((f = 1), + y && + (t = + op[0] & 2 + ? y['return'] + : op[0] + ? y['throw'] || ((t = y['return']) && t.call(y), 0) + : y.next) && + !(t = t.call(y, op[1])).done) + ) + return t; + if (((y = 0), t)) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if ( + !((t = _.trys), (t = t.length > 0 && t[t.length - 1])) && + (op[0] === 6 || op[0] === 2) + ) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + }; +Object.defineProperty(exports, '__esModule', { value: true }); +var Database = /** @class */ (function () { + function Database() { + var collections = Object.create(null); + this._collections = collections; + var proxy = new Proxy(this, { + get: function (target, prop) { + if (prop in target) { + return target[prop]; + } + if (typeof prop !== 'string' || prop.startsWith('_')) { + return; + } + if (!collections[prop]) { + collections[prop] = new Collection(); + } + return collections[prop]; + }, + }); + return proxy; + } + return Database; +})(); +var Collection = /** @class */ (function () { + function Collection() {} + Collection.prototype.find = function (query) { + return Promise.resolve(query); + }; + return Collection; +})(); +function run() { + return __awaiter(this, void 0, void 0, function () { + var database, coll, _a, _b; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + database = new Database(); + coll = database.myCollection; + _b = (_a = console).log; + return [4 /*yield*/, database.myCollection.find({ name: 'foo' })]; + case 1: + _b.apply(_a, [_c.sent()]); + return [2 /*return*/]; + } + }); + }); +} +run().catch(console.error); diff --git a/packages/mql-typescript/tests/real.ts b/packages/mql-typescript/tests/real.ts new file mode 100644 index 00000000..9018bf1f --- /dev/null +++ b/packages/mql-typescript/tests/real.ts @@ -0,0 +1,72 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import type * as schema from '../out/schema'; +import type { Document } from 'bson'; + +type StringKey = keyof T & string; +interface GenericDatabaseSchema { + [key: string]: GenericCollectionSchema; +} + +interface GenericCollectionSchema { + schema: Document; +} + +class Database { + _collections: Record, CollectionWithSchema>; + + constructor() { + const collections: Record> = Object.create( + null, + ); + this._collections = collections; + const proxy = new Proxy(this, { + get(target: any, prop: string): any { + if (prop in target) { + return target[prop]; + } + + if (typeof prop !== 'string' || prop.startsWith('_')) { + return; + } + + if (!collections[prop]) { + collections[prop] = + new Collection() as unknown as CollectionWithSchema; + } + + return collections[prop]; + }, + }); + return proxy; + } +} + +type DatabaseWithSchema< + D extends GenericDatabaseSchema = GenericDatabaseSchema, +> = Database & { + [k in StringKey]: Collection; +}; +class Collection< + D extends GenericDatabaseSchema = GenericDatabaseSchema, + C extends GenericCollectionSchema = GenericCollectionSchema, +> { + find(query: schema.Query): Promise> { + return Promise.resolve(query); + } +} +type CollectionWithSchema< + D extends GenericDatabaseSchema = GenericDatabaseSchema, + C extends GenericCollectionSchema = D[keyof D], +> = Collection; + +type dbSchema = { + myCollection: { schema: { name: string } }; +}; + +async function run() { + const database = new Database() as DatabaseWithSchema; + const coll = database.myCollection; + console.log(await database.myCollection.find({ name: 'foo' })); +} + +run().catch(console.error);