Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ronin/schema

Package Overview
Dependencies
Maintainers
0
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ronin/schema - npm Package Compare versions

Comparing version 0.1.4 to 0.1.5

238

dist/index.d.ts

@@ -109,2 +109,3 @@ /**

type ModelFieldCollation = 'BINARY' | 'NOCASE' | 'RTRIM';
type ModelFieldLinkAction = 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'SET DEFAULT' | 'NO ACTION';
type ModelFieldBasics = {

@@ -143,27 +144,45 @@ /** The label that should be used when displaying the field on the RONIN dashboard. */

check?: Expression;
/**
* If the field is of type `string`, setting this attribute defines the collation
* sequence to use for the field value.
*/
};
type ModelField = ModelFieldBasics & ({
/** The kind of value that should be stored inside the field. */
type?: never;
} | {
/** The kind of value that should be stored inside the field. */
type: 'boolean';
} | {
/** The kind of value that should be stored inside the field. */
type: 'date';
} | {
/** The kind of value that should be stored inside the field. */
type: 'json';
} | {
/** The kind of value that should be stored inside the field. */
type: 'blob';
} | {
/** The kind of value that should be stored inside the field. */
type: 'string';
/** The collation sequence to use for the field value. */
collation?: ModelFieldCollation;
} | {
/** The kind of value that should be stored inside the field. */
type: 'number';
/**
* If the field is of type `number`, setting this attribute will automatically increment
* the value of the field with every new record that gets inserted.
* Automatically increments the value of the field with every new inserted record.
*/
increment?: boolean;
};
type ModelFieldNormal = ModelFieldBasics & {
type?: 'string' | 'number' | 'boolean' | 'date' | 'json';
};
type ModelFieldReferenceAction = 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'SET DEFAULT' | 'NO ACTION';
type ModelFieldReference = ModelFieldBasics & {
} | {
/** The kind of value that should be stored inside the field. */
type: 'link';
/** The target model of the relationship that is being established. */
target: string;
/** Whether the field should be related to one record, or many records. */
kind?: 'one' | 'many';
/**
* If the target record is updated or deleted, the defined actions maybe executed.
*/
actions?: {
onDelete?: ModelFieldReferenceAction;
onUpdate?: ModelFieldReferenceAction;
onDelete?: ModelFieldLinkAction;
onUpdate?: ModelFieldLinkAction;
};
};
type ModelField = ModelFieldNormal | ModelFieldReference;
});
type ModelIndexField<T extends Array<ModelField> = Array<ModelField>> = {

@@ -274,3 +293,9 @@ /** The collating sequence used for text placed inside the field. */

interface RoninFields {
/**
* The unique identifier for this record.
*/
id: string;
/**
* Contains metadata about the record like creation date, last update, etc.
*/
ronin: string;

@@ -283,7 +308,19 @@ }

interface Model<Fields> extends Omit<PublicModel, 'fields' | 'indexes' | 'triggers' | 'presets'> {
/**
* The fields that make up this model.
*/
fields?: Fields;
/**
* Predefined query instructions that can be reused across multiple different queries.
*/
presets?: Record<string, GetInstructions | WithInstruction>;
/**
* Database indexes to optimize query performance.
*/
indexes?: Array<ModelIndex<Array<ModelField & {
slug: keyof Fields;
}>>>;
/**
* Queries that run automatically in response to other queries.
*/
triggers?: Array<ModelTrigger<Array<ModelField & {

@@ -293,38 +330,5 @@ slug: keyof Fields;

}
interface FieldGeneric {
/**
* The visual display name of the field.
*/
name?: string;
}
interface SerializedField<T> {
/**
* Whether the field is required.
*/
required: boolean;
/**
* The value that the field should provide in the case of a missing value.
*/
defaultValue?: T | null;
/**
* Whether the field's value should be unique across all records of the model.
*/
unique: boolean;
/**
* Whether the field's value should be incremented automatically with each new record.
* Only available for number fields.
*/
increment: T extends number ? boolean : never;
}
interface LinkField {
actions?: {
onDelete?: 'cascade' | 'restrict' | 'set null' | 'no action';
onUpdate?: 'cascade' | 'restrict' | 'set null' | 'no action';
};
model: RoninFields | {
slug: string;
};
}
interface SerializedLinkField extends Omit<Partial<SerializedField<string>>, 'increment'>, LinkField {
}
type SerializedField<Type> = Partial<Omit<Extract<ModelField, {
type: Type;
}>, 'slug' | 'type'>>;
type FieldsToTypes<F> = F extends Record<string, Primitives> ? {

@@ -372,6 +376,16 @@ [K in keyof F]: F[K] extends Record<string, Primitives> ? FieldsToTypes<F[K]> : F[K]['type'] extends 'string' ? string : F[K]['type'] extends 'number' ? number : F[K]['type'] extends 'boolean' ? boolean : F[K]['type'] extends 'link' ? string : F[K]['type'] extends 'json' ? object : F[K]['type'] extends 'blob' ? Blob : F[K]['type'] extends 'date' ? Date : never;

*/
declare const blob: (attributes?: Omit<Partial<SerializedField<string>>, "increment"> & FieldGeneric) => {
declare const blob: (attributes?: SerializedField<"blob">) => {
displayAs?: string | undefined;
unique?: boolean | undefined;
required?: boolean | undefined;
defaultValue?: string | null | undefined;
unique?: boolean | undefined;
defaultValue?: unknown;
computedAs?: {
kind: "VIRTUAL" | "STORED";
value: {
__RONIN_EXPRESSION: string;
};
} | undefined;
check?: {
__RONIN_EXPRESSION: string;
} | undefined;
name: string | undefined;

@@ -389,6 +403,16 @@ type: "blob";

*/
declare const boolean: (attributes?: Omit<Partial<SerializedField<boolean>>, "increment"> & FieldGeneric) => {
declare const boolean: (attributes?: SerializedField<"boolean">) => {
displayAs?: string | undefined;
unique?: boolean | undefined;
required?: boolean | undefined;
defaultValue?: boolean | null | undefined;
unique?: boolean | undefined;
defaultValue?: unknown;
computedAs?: {
kind: "VIRTUAL" | "STORED";
value: {
__RONIN_EXPRESSION: string;
};
} | undefined;
check?: {
__RONIN_EXPRESSION: string;
} | undefined;
name: string | undefined;

@@ -406,6 +430,16 @@ type: "boolean";

*/
declare const date: (attributes?: Omit<Partial<SerializedField<string | Date>>, "increment"> & FieldGeneric) => {
declare const date: (attributes?: SerializedField<"date">) => {
displayAs?: string | undefined;
unique?: boolean | undefined;
required?: boolean | undefined;
defaultValue?: string | Date | null | undefined;
unique?: boolean | undefined;
defaultValue?: unknown;
computedAs?: {
kind: "VIRTUAL" | "STORED";
value: {
__RONIN_EXPRESSION: string;
};
} | undefined;
check?: {
__RONIN_EXPRESSION: string;
} | undefined;
name: string | undefined;

@@ -415,5 +449,2 @@ type: "date";

interface JsonAttributes {
displayAs?: 'rich-text';
}
/**

@@ -427,8 +458,17 @@ * Creates a JSON field definition returning an object that includes the field type

*/
declare const json: (attributes?: Omit<Partial<SerializedField<string | object>>, "increment"> & FieldGeneric & JsonAttributes) => {
declare const json: (attributes?: SerializedField<"json">) => {
unique?: boolean | undefined;
required?: boolean | undefined;
defaultValue?: string | object | null | undefined;
unique?: boolean | undefined;
defaultValue?: unknown;
computedAs?: {
kind: "VIRTUAL" | "STORED";
value: {
__RONIN_EXPRESSION: string;
};
} | undefined;
check?: {
__RONIN_EXPRESSION: string;
} | undefined;
name: string | undefined;
displayAs: "rich-text" | undefined;
displayAs: string | undefined;
type: "json";

@@ -445,6 +485,16 @@ };

*/
declare const number: (attributes?: Partial<SerializedField<number>> & FieldGeneric) => {
declare const number: (attributes?: SerializedField<"number">) => {
displayAs?: string | undefined;
unique?: boolean | undefined;
required?: boolean | undefined;
defaultValue?: number | null | undefined;
unique?: boolean | undefined;
defaultValue?: unknown;
computedAs?: {
kind: "VIRTUAL" | "STORED";
value: {
__RONIN_EXPRESSION: string;
};
} | undefined;
check?: {
__RONIN_EXPRESSION: string;
} | undefined;
increment?: boolean | undefined;

@@ -463,13 +513,22 @@ name: string | undefined;

*/
declare const link: (attributes: SerializedLinkField & FieldGeneric) => {
declare const link: (attributes?: SerializedField<"link">) => {
displayAs?: string | undefined;
unique?: boolean | undefined;
required?: boolean | undefined;
defaultValue?: string | null | undefined;
unique?: boolean | undefined;
defaultValue?: unknown;
computedAs?: {
kind: "VIRTUAL" | "STORED";
value: {
__RONIN_EXPRESSION: string;
};
} | undefined;
check?: {
__RONIN_EXPRESSION: string;
} | undefined;
kind?: ("one" | "many") | undefined;
name: string | undefined;
model: RoninFields | {
slug: string;
};
target: string;
actions: {
onDelete?: "cascade" | "restrict" | "set null" | "no action";
onUpdate?: "cascade" | "restrict" | "set null" | "no action";
onDelete?: "CASCADE" | "RESTRICT" | "SET NULL" | "SET DEFAULT" | "NO ACTION";
onUpdate?: "CASCADE" | "RESTRICT" | "SET NULL" | "SET DEFAULT" | "NO ACTION";
} | undefined;

@@ -479,5 +538,2 @@ type: "link";

interface StringAttributes {
displayAs?: 'single-line' | 'multi-line' | 'secret';
}
/**

@@ -491,8 +547,18 @@ * Creates a string field definition returning an object that includes the field type

*/
declare const string: (attributes?: Omit<Partial<SerializedField<string>>, "increment"> & FieldGeneric & StringAttributes) => {
declare const string: (attributes?: SerializedField<"string">) => {
unique?: boolean | undefined;
required?: boolean | undefined;
defaultValue?: string | null | undefined;
unique?: boolean | undefined;
defaultValue?: unknown;
computedAs?: {
kind: "VIRTUAL" | "STORED";
value: {
__RONIN_EXPRESSION: string;
};
} | undefined;
check?: {
__RONIN_EXPRESSION: string;
} | undefined;
collation?: ("BINARY" | "NOCASE" | "RTRIM") | undefined;
name: string | undefined;
displayAs: "single-line" | "multi-line" | "secret";
displayAs: string;
type: "string";

@@ -499,0 +565,0 @@ };

@@ -919,8 +919,8 @@ var __create = Object.create;

// src/model/primitives/link.ts
var link = (attributes) => {
const { name, model: model2, actions, ...rest } = attributes;
if (!model2) throw new Error("A model is required for a link field");
var link = (attributes = {}) => {
const { name, target, actions, ...rest } = attributes;
if (!target) throw new Error("A model is required for a link field");
return {
name,
model: model2,
target,
actions,

@@ -943,2 +943,54 @@ type: "link",

// src/model/utils/errors.ts
var RoninError = class extends Error {
code;
model;
field;
fields;
issues;
constructor(details) {
super(details.message);
this.name = "RoninError";
this.code = details.code;
this.model = details.model;
this.field = details.field;
this.fields = details.fields;
this.issues = details.issues;
}
};
var throwForbiddenModelDefinition = (model2) => {
const { fields, indexes, slug } = model2;
for (const [fieldSlug, _field] of Object.entries(fields ?? {})) {
if (fieldSlug === "id") {
throw new RoninError({
message: 'The field "id" is reserved and cannot be used.',
code: "FIELD_RESERVED",
model: slug,
field: "id"
});
}
}
if (indexes && indexes.length > 0) {
for (const index of indexes) {
if (index.fields.length === 0) {
throw new RoninError({
message: "An index must have at least one field.",
code: "INDEX_NO_FIELDS",
model: slug
});
}
for (const field of index.fields) {
if ("slug" in field && fields && fields[field.slug] === void 0) {
throw new RoninError({
message: `The field ${field.slug} does not exist in this model.`,
code: "FIELD_NOT_DEFINED",
field: field.slug,
model: slug
});
}
}
}
}
};
// node_modules/ronin/node_modules/@ronin/compiler/dist/index.js

@@ -1038,3 +1090,3 @@ var import_cuid2 = __toESM(require_cuid2(), 1);

const { type, unique, defaultValue, required, name } = value;
const { actions, model: model2 } = value;
const { actions, target } = value;
return {

@@ -1046,6 +1098,4 @@ slug: key,

defaultValue,
// @ts-expect-error: The `type` property exists in the model.
type,
// @ts-expect-error: The `target` property exists in the model.
target: model2?.slug,
target,
actions

@@ -1101,14 +1151,3 @@ };

} = model2;
if (indexes && indexes.length > 0) {
for (const index of indexes) {
if (index.fields.length === 0) {
throw new Error("An index must have at least one field.");
}
for (const field of index.fields) {
if ("slug" in field && fields && fields[field.slug] === void 0) {
throw new Error(`The field ${field.slug} does not exist in this model.`);
}
}
}
}
throwForbiddenModelDefinition(model2);
return {

@@ -1115,0 +1154,0 @@ slug,

{
"name": "@ronin/schema",
"version": "0.1.4",
"version": "0.1.5",
"type": "module",

@@ -32,3 +32,3 @@ "description": "Allows for defining the schema of a RONIN database in code.",

"@biomejs/biome": "1.9.4",
"@ronin/compiler": "0.13.1",
"@ronin/compiler": "0.13.8",
"@types/bun": "1.1.14",

@@ -35,0 +35,0 @@ "ronin": "5.3.5",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc