UNPKG

cosmos-orm

Version:
225 lines (222 loc) 7.79 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { BaseModel: () => BaseModel, createClient: () => createClient }); module.exports = __toCommonJS(src_exports); // src/base-model.ts var import_functions = require("@azure/functions"); var import_ulidx = require("ulidx"); var BaseModel = class { constructor(options) { this.options = options; if (options.connectionStringSetting) { this.connectionStringSetting = options.connectionStringSetting; } if (typeof this.options === "boolean" && !this.options) { this.fields = { id: false, timestamp: false }; } if (typeof this.options === "object") { this.fields = { ...this.fields, // Don't know why this won't remove the bool type ...this.options.fields }; } this.client = options.client.database(options.database).container(options.container); } client; connectionStringSetting = "COSMOS_CONNECTION_STRING"; fields = { id: true, timestamp: true }; /** * Create an Azure Function app input binding to find a specific document by an input variable. * You can also provide a type (matching `Record<string, any>`) as the first type generic, * and it will validate the variable to be one of the types keys. * * @example * ```ts * const shopInput = orm.shops.createFindBinding(`shop`) * ``` * @example * An example with a type to check the variable: * ```ts * interface ActivityInput { * shop: string * // ... * } * * const shopDocument = orm.shops.createFindBinding<ActivityInput>('shop') // ✅ * const shopDocument2 = orm.shops.createFindBinding<ActivityInput>('id') // ❌ * ``` */ createFindBinding(variable) { const binding = `{${variable}}`; return import_functions.input.cosmosDB({ databaseName: this.options.database, containerName: this.options.container, connection: this.connectionStringSetting, id: binding, partitionKey: binding }); } /** Create an Azure Function app input binding to fetch all documents from this container. */ createAllBinding() { return import_functions.input.cosmosDB({ databaseName: this.options.database, containerName: this.options.container, connection: this.connectionStringSetting }); } /** * Create an Azure Function app input binding with a custom SQL query. * @example * ```ts * const inputDoc = orm.posts.createSQLBinding(`SELECT * FROM c WHERE c.deleted_at IS NULL`) * ``` */ createSQLBinding(sqlQuery) { return import_functions.input.cosmosDB({ databaseName: this.options.database, containerName: this.options.container, connection: this.connectionStringSetting, sqlQuery }); } /** Fetch all resources in a container */ async all() { const { resources } = await this.client.items.readAll().fetchAll(); return resources; } /** Fetch a specific resource by its ID */ async find(id) { const { resource } = await this.client.item(id, id).read(); return resource; } /** Fetch multiple resources using their ID's */ async findMany(ids) { const { resources } = await this.client.items.query({ query: "SELECT * FROM C WHERE ARRAY_CONTAINS(@ids, C.id)", parameters: [{ name: "@ids", value: ids }] }).fetchAll(); return resources; } /** Find a resource by a specific key */ async findBy(key, value) { const { resources } = await this.client.items.query({ query: "SELECT * FROM C WHERE C[@key] = @value OFFSET 0 LIMIT 1", parameters: [ { name: "@key", value: String(key) }, { name: "@value", value } ] }).fetchAll(); const [resource] = resources; return resource; } /** Find multiple resources by a specific key */ async findManyBy(key, value) { const { resources } = await this.client.items.query({ query: "SELECT * FROM C WHERE C[@key] = @value", parameters: [ { name: "@key", value: String(key) }, { name: "@value", value } ] }).fetchAll(); const [resource] = resources; return resource; } /** Create a resource */ async create(input2) { const merged = { ...input2, id: this.fields.id ? (0, import_ulidx.ulid)() : input2.id, createdAt: this.fields.timestamp ? (/* @__PURE__ */ new Date()).toISOString() : input2.createdAt, updatedAt: this.fields.timestamp ? (/* @__PURE__ */ new Date()).toISOString() : input2.updatedAt }; const { resource } = await this.client.items.create(merged); return resource; } /** Either update or create a resource */ async upsert(input2) { const { resource } = await this.client.items.upsert(input2); return resource; } /** Update a resource - replaces the whole resource, so make sure to provide a full input */ async replace(id, input2) { const merged = { ...input2, updatedAt: this.fields.timestamp ? (/* @__PURE__ */ new Date()).toISOString() : input2.updatedAt }; const { resource } = await this.client.item(id, id).replace(merged); return resource; } /** Delete a resource */ async delete(id) { const { resource } = await this.client.item(id, id).delete(); return resource; } /** * Run a query, and fetch all results * * This function accepts a generic, so you can pass in the type of the response if * you are running a custom select query - for example: * * `.query<{ id: string }>('SELECT c.id FROM c') // returns { id: string }[]` * * `.query<number>('SELECT VALUE count(c.id) FROM c') // returns [number]` * * This is just a wrapper of the `.client.items.query()` function, so you can use that * instead if you need access to the request metrics for example. */ // biome-ignore lint/suspicious/noExplicitAny: <explanation> async query(query, options) { const { resources } = await this.client.items.query(query, options).fetchAll(); return resources; } }; // src/config.ts var import_cosmos = require("@azure/cosmos"); function createClient(options) { const connectionStringSetting = options.connectionStringSetting || "COSMOS_CONNECTION_STRING"; const connectionString = options.connectionString ?? process.env[connectionStringSetting]; if (typeof connectionString !== "string") { if (options.connectionString) throw new Error("Missing connection string value (from `options.connectionString`)"); throw new Error(`Missing connection string for ${connectionStringSetting}`); } const client = new import_cosmos.CosmosClient(connectionString); const builder = { createModel: (container, config = {}) => new BaseModel({ client, container, ...options, ...config }) }; const models = options.models(builder); return { client, ...models }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { BaseModel, createClient }); //# sourceMappingURL=index.js.map