@eristack/entity-id
Version:
UUID v7 entity identifiers — sortable, parseable, Drizzle column helper
127 lines (120 loc) • 4.19 kB
JavaScript
;
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/drizzle/index.ts
var drizzle_exports = {};
__export(drizzle_exports, {
entityIdColumn: () => entityIdColumn,
entityIdPgColumn: () => entityIdPgColumn
});
module.exports = __toCommonJS(drizzle_exports);
// src/drizzle/column.ts
var import_pg_core = require("drizzle-orm/pg-core");
var import_mysql_core = require("drizzle-orm/mysql-core");
var import_sqlite_core = require("drizzle-orm/sqlite-core");
// src/core/errors.ts
var ENTITY_ID_PARSE_CODE = "ENTITY_ID_PARSE";
var EntityIdParseError = class extends Error {
code = ENTITY_ID_PARSE_CODE;
constructor(message) {
super(message);
this.name = "EntityIdParseError";
}
};
// src/core/types.ts
var MAX_ENTITY_ID_UNIX_MS = 281474976710655;
// src/core/internal.ts
function bytesToCanonicalUuid(bytes) {
const hex = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
const canonical = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
return canonical;
}
function generateEntityIdBytes(unixMs, random) {
if (!Number.isFinite(unixMs) || unixMs < 0 || unixMs > MAX_ENTITY_ID_UNIX_MS) {
throw new EntityIdParseError(
`Unix timestamp ms out of range for UUID v7 (0..${MAX_ENTITY_ID_UNIX_MS})`
);
}
if (random.length < 10) {
throw new EntityIdParseError("Random bytes must be at least 10 octets");
}
const ts = BigInt(Math.trunc(unixMs));
const bytes = new Uint8Array(16);
bytes[0] = Number(ts >> 40n & 0xffn);
bytes[1] = Number(ts >> 32n & 0xffn);
bytes[2] = Number(ts >> 24n & 0xffn);
bytes[3] = Number(ts >> 16n & 0xffn);
bytes[4] = Number(ts >> 8n & 0xffn);
bytes[5] = Number(ts & 0xffn);
bytes[6] = random[0] & 15 | 112;
bytes[7] = random[1];
bytes[8] = random[2] & 63 | 128;
bytes[9] = random[3];
bytes[10] = random[4];
bytes[11] = random[5];
bytes[12] = random[6];
bytes[13] = random[7];
bytes[14] = random[8];
bytes[15] = random[9];
return bytes;
}
// src/core/entity-id.ts
function randomOctets(length) {
const bytes = new Uint8Array(length);
crypto.getRandomValues(bytes);
return bytes;
}
function generateEntityId(unixMs = Date.now()) {
const rnd = randomOctets(10);
const bytes = generateEntityIdBytes(unixMs, rnd);
return bytesToCanonicalUuid(bytes);
}
// src/drizzle/column.ts
function pgsqlEntityIdColumn(sqlName) {
return (0, import_pg_core.uuid)(sqlName).$defaultFn(() => generateEntityId());
}
function mysqlEntityIdColumn(sqlName) {
return (0, import_mysql_core.char)(sqlName, { length: 36 }).$defaultFn(() => generateEntityId());
}
function sqliteEntityIdColumn(sqlName) {
return (0, import_sqlite_core.text)(sqlName).$defaultFn(() => generateEntityId());
}
function entityIdColumn(dialect, name, options) {
const sqlName = options?.sqlName ?? name;
switch (dialect) {
case "pgsql":
return pgsqlEntityIdColumn(sqlName);
case "mysql":
return mysqlEntityIdColumn(sqlName);
case "sqlite":
return sqliteEntityIdColumn(sqlName);
default: {
const _exhaustive = dialect;
throw new Error(`Unsupported dialect: ${String(_exhaustive)}`);
}
}
}
function entityIdPgColumn(name, options) {
return entityIdColumn("pgsql", name, options);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
entityIdColumn,
entityIdPgColumn
});
//# sourceMappingURL=index.cjs.map