A simple, strictly typed ORM, to assist you in using Cloudflare's D1 product

Overview

D1-Orm

A simple, strictly typed ORM, to assist you in using Cloudflare's D1 product

API reference can be found at https://d1-orm.pages.dev/modules

Docs can be found at https://d1-orm.pages.dev/guides

Installation

This package can be found on NPM

$ npm install d1-orm

Usage

This package is recommended to be used with @cloudflare/workers-types 3.16.0+.

import { D1Orm, DataTypes, Model } from "d1-orm";
import type { Infer } from "d1-orm";

export interface Env {
	// from @cloudflare/workers-types
	DB: D1Database;
}

export default {
	async fetch(request: Request, env: Env) {
		const orm = new D1Orm(env.DB);
		const users = new Model(
			{
				D1Orm: orm,
				tableName: "users",
			},
			{
				id: {
					type: DataTypes.INTEGER,
					primaryKey: true,
					autoIncrement: true,
					notNull: true,
				},
				name: {
					type: DataTypes.STRING,
					notNull: true,
					defaultValue: "John Doe",
				},
				email: {
					type: DataTypes.STRING,
					unique: true,
				},
			}
		);
		type User = Infer<typeof users>;

		await users.First({
			where: {
				id: 1,
			},
		});
		// Promise<User | null>
	},
};

For more information, refer to the docs.

Comments
  • Add support for boolean datatype

    Add support for boolean datatype

    Sqlite supports a boolean datatype which gets automatically coerced into a 0 or 1.

    The new datatype was added, along with type coercion to support all the query types.

    The change to support this ends up being fairly trivial, but I would love feedback and any thoughts on the implementation or suggestions on alteration.

    I think this implementation sets it up to allow other types of coercion with even less updates.

    opened by kingmesal 12
  • Unique Keys - Multi-column

    Unique Keys - Multi-column

    Wanted to see if you have any ideas on how to structure a multi-column unique key?

    The following model:

            username: {
                type: DataTypes.STRING,
                unique: true,
                notNull: true,
            },
            session: {
                type: DataTypes.STRING,
                unique: true,
                notNull: true,
            },
    

    Producing a table like:

    CREATE TABLE users (
    usename text not null unique,
    session text not null unique
    );
    

    produces a table which does not allow the same username to be inserted into multiple records.

    In reality what is needed is:

            username: {
                type: DataTypes.STRING,
                notNull: true,
            },
            session: {
                type: DataTypes.STRING,
                notNull: true,
            },
            uniqueKeys: { [username, session], ... },
    

    which when generated would produce

    CREATE TABLE users (
    usename text not null,
    session text not null,
        UNIQUE (username, session) // This means the combination must be unique.
    );
    

    The benefit of this type of approach means foreign key definition support would be able to piggy back. Foreign keys have a few more options, but the basics are the most important part...

    enhancement 
    opened by kingmesal 5
  • boolean default value use case not covered

    boolean default value use case not covered

    https://github.com/Interactions-as-a-Service/d1-orm/commit/b214e74a5c7c56fb593008b87bf819affb52fb47

    Does not provide support for a boolean default value.

    bug 
    opened by kingmesal 5
  • boolean type

    boolean type

    Is your feature request related to a problem? Please describe. I was trying to create a schema but the boolean type was missing

    Describe the solution you'd like Adding the boolean type

    Describe alternatives you've considered Using ints

    Additional context I could make a pull request to add this if you want me to.

    enhancement 
    opened by Tricked-dev 5
  • Fix README as Model Options property name

    Fix README as Model Options property name

    In README.md, the Model options propety name primaryKeys is incorrect, which is now primaryKey. I fixed it.

    Resource: https://github.com/Interactions-as-a-Service/d1-orm/blob/e418a4f7455652853df951d1da6d8ca447d24391/src/model.ts#L22

    opened by nikukyugamer 2
  • Prefer single quotes over double quotes

    Prefer single quotes over double quotes

    Describe the bug When specifying a string defaultValue for a given model, the value is "encoded" with double quotes in the create statement. While this is technically ok with SQLite, it is actually not best practice (https://www.sqlite.org/quirks.html). While I understand that this is not a high-priority issue, it is causing downstream issues for me when use this for local development, so I thought I would submit an issue in case it is hitting anyone else. I'm happy to submit a PR for this (tiny) fix, if that would be accepted.

    The following section of a model:

    ...
    name: {
      type: DataTypes.STRING,
      notNull: true,
      defaultValue: "John Doe",
    },
    ...
    

    runs into this on line 138 of current main:

    defaultStr = `"${column.defaultValue}"`;
    

    Expected behavior

    That line should probably be

    defaultStr = `'${column.defaultValue}'`;
    
    bug 
    opened by carsonfarmer 2
  • [breaking] Feat: Refactor models to allow multiple unique keys

    [breaking] Feat: Refactor models to allow multiple unique keys

    Closes #53

    This change restructures the way that primary keys, auto increment keys and unique keys are provided. This allows for multiple unique keys to be provided for a model. These fields have been moved from the ModelColumn type to the first parameter in the Model constructor.

    This also fixes non-string default values, such as numbers & booleans, by suppling them as is

    Docs

    These are now located at https://docs.interactions.rest/d1-orm/

    enhancement 
    opened by Skye-31 2
  • Inferred types!

    Inferred types!

    Models no longer require you to specify a definition when you create them. Instead, you can just pass in an object and the model will infer the types for you. See the following example:

    import { Model, DataTypes } from "d1-orm";
    + import type { Infer } from "d1-orm";
    
    - const users = new Model<User>(
    + const users = new Model(
    	{
    		tableName: "users",
    		D1Orm: MyD1OrmInstance,
    	},
    	{
    		name: {
                         type: DataTypes.TEXT,
                    },
    		age: {
                        type: DataTypes.INTEGER,
                    }
    	}
    );
    
    + type User = Infer<typeof users>;
    - type User = {
    -   name: string,
    -   age: number
    - }
    
    enhancement 
    opened by Skye-31 2
  • Fix NPM link

    Fix NPM link

    What?

    The NPM package link used a relative path which was opening a non existent url, on this PR we change this to an absolute URL to avoid this issue.

    opened by david8z 2
  • Version Packages

    Version Packages

    This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

    Releases

    [email protected]

    Minor Changes

    • #21 b2559ef Thanks @Skye-31! - [breaking] feat: Switch to use a QueryBuilder instead of duplicate code in the Model class

      This will be much more expandable in future to support things like advanced where querying, using operators other than AND, joins, etc.

    Patch Changes

    • #26 bc18cce Thanks @Skye-31! - Chore: Add a build test

      Also ensure that the lib is built before publishing.

    • #25 1750a55 Thanks @Skye-31! - Chore: readable guides for interacting with the library Closes #22

    Version Packages 
    opened by github-actions[bot] 2
  • Refactor to QueryBuilder

    Refactor to QueryBuilder

    Todo: Tests:

    • [x] Select
    • [x] Update
    • [x] Insert
    • [x] Delete

    Implementations:

    • [x] Select
    • [x] Update
    • [x] Insert
    • [x] Delete

    Refactoring Model to use this:

    • [x] First
    • [x] All
    • [x] InsertOne
    • [x] InsertMany
    • [x] Update
    • [x] Upsert?
    opened by Skye-31 2
  • Add support for passing a unique column to queryBuilder for UPSERT st…

    Add support for passing a unique column to queryBuilder for UPSERT st…

    The default primary key does work but is not suitable for all situations, there are use cases that need an email or an api key to be used as the conflicting column.

    opened by azeemhassni 1
  • Add Foreign Key Support

    Add Foreign Key Support

    Adding on to #53 ...

    For foreign keys there are a number of options a foreign key may have, but from a definition standpoint adding the foreign key to the column definition make the most sense as each column may only reference a single foreign column.

    What I propose is the following:

    {
      username: {
        type: DataTypes.STRING,
        unique: "some-arbitrary-key",
      },
      session: {
        type: DataTypes.STRING,
        foreignKey: {
          table: "session-table", // example like Model.tableName
          column: "session-table-field-name", // example like Model.columnName
          onDelete?: {
              cascade?: boolean,
              restrict?: boolean,
              setNull?: boolean,
              setDefault?: boolean,
          },
          onUpdate?: {
              cascade?: boolean,
              restrict?: boolean,
              setNull?: boolean,
              setDefault?: boolean,
          },
        },
      },
    }
    

    I think this approach is fairly straight-forward and easy to follow.

    Thoughts?

    enhancement 
    opened by kingmesal 3
Releases(v0.7.2)
Experience Lab is a set of utilities that assist in creating instances of Microsoft Energy Data Services, performing data loads, and performing basic management operations.

Experience Lab - Microsoft Energy Data Services Build Status About Experience Lab is an automated, end-to-end deployment accelerator for Microsoft Ene

Microsoft 9 Dec 14, 2022
Demonstration of how you build full-stack, typed, NPM packages, the right way

NPM Packages - The Right way This repository aims to demonstrate how to build NPM packages the right way. my-package should import the shared code, bu

VulcanJS 61 Nov 27, 2022
Lazy minting of ERC721 NFTs using EIP712 standard for typed, structured data. ✨

ERC721 - Signature minting Lazy minting of ERC721 NFTs using EIP712 standard for typed, structured data. ✨ How it works Lazy minting or Signature mint

Sunrit Jana 21 Oct 20, 2022
A product system made with NestJS. It's a service where you list products, create products or even delete them.

Products-API A product system made with NestJS. It's a service where you list products, create products or even delete them. What I used in this proje

Luiz Sanches 4 May 18, 2022
Typed HyperText Markup Language

Typed HyperText Markup Language You can add types to the HyperText Markup Language. Types To declare two types, they must be separated by a period and

TypeMarkup 1 Jan 22, 2022
io-ts Typed Event Bus for the runtime of your Node.js application. A core for any event-driven architecture based app.

Typed Event Bus Based on io-ts types, this bus provides a handy interface to publish and consume events in the current runtime of the Node.js process.

Konstantin Knyazev 3 May 23, 2022
A fully-typed, low-level, and HyperScript-like Frontend Library 🚀

A fully-typed, low-level, and HyperScript-like Frontend Library ??

Eliaz Bobadilla 5 Apr 4, 2022
Small, typed, dependency free tool to round corners of 2d-polygon provided by an array of { x, y } points.

round-polygon Small, typed, dependency-free tool to round corners of 2d-polygon provided by an array of { x, y } points. The algorithm prevents roundi

Sergey Borovikov 10 Nov 26, 2022
Tpy - A strongly typed Pylon API client

tpy A strongly typed Pylon API client. https://pylon.bot/ The Pylon API does not have a standardized response, meaning there are alot of edge cases an

insyri 6 Dec 15, 2022
easily building data structures that are serializable, validatable, and fully typed.

@davecode/structures [beta/wip] Structures is a TypeScript library for easily building data structure classes that are Serializable: Can convert rich

Dave Caruso 2 May 22, 2022
A zero-dependency, strongly-typed web framework for Bun, Node and Cloudflare workers

nbit A simple, declarative, type-safe way to build web services and REST APIs for Bun, Node and Cloudflare Workers. Examples See some quick examples b

Simon Sturmer 16 Sep 16, 2022
End-to-end typed monorepo template for your next project ⌨️

TYPE ⌨️ TRPC + Yarn Monorepo + Prisma + Expo This template project is a Yarn monorepo with full end-to-end type safety. Powered by: TRPC (on Fastify)

Matteo Lobello 35 Oct 22, 2022
📦 Fully typed and immutable store made on top of Immer with mutation, action, subscription and validation!

Riux is a fully typed and immutable store made on top of Immer with mutation, action, subscription and validation! Table of contents ?? Installation U

null 10 Aug 27, 2022
Fully-typed utilities for defining, validating and building your document

zhead Typed utilities for defining, validating and building best-practice document <head>'s. Status: Pre-release Please report any issues ?? Made poss

Harlan Wilton 70 Dec 21, 2022
📃 Typed primitives for Typescript to work with file paths

typed-file-system-path typed-file-system-path takes inspiration from Path.swift in swift-tools-support-core and provides typed primitives to work with

Craftweg 6 Dec 15, 2022
Simple scripts for crawling shopee's shop and product information from shopee.vn

Table of Contents About The Project Built With Getting Started Prerequisites Installation Usage License About The Project shopee-crawler is a simple p

Hoàng Kim Minh 5 Dec 13, 2022
Simple jQuery plugin that will allow users to zoom in your images, perfect for product images and galleries.

Image Zoom (jQuery) Plugin Simple jQuery plugin that will allow users to zoom in your images, perfect for product images and galleries that is less th

Mario Duarte 8 Aug 3, 2022
A simple, lightweight, clean and small library for creating guided product tours for your web app.

Tourguide.js Simple, lightweight library for creating guided tours for your web, apps and more. A tour guide is a person who provides assistance, info

Docsie.io 277 Dec 12, 2022
JS Cloudimage 360 View - A simple, interactive resource that can be used to provide a virtual tour of your product

JS Cloudimage 360 View - A simple, interactive resource that can be used to provide a virtual tour of your product

Scaleflex 1.9k Jan 7, 2023