New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@ronin/compiler

Package Overview
Dependencies
Maintainers
0
Versions
379
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ronin/compiler - npm Package Compare versions

Comparing version 0.9.0 to 0.10.0-leo-ron-1083-experimental-206

300

dist/index.js

@@ -23,2 +23,8 @@ // src/utils/helpers.ts

);
var MODEL_ENTITY_ERROR_CODES = {
field: "FIELD_NOT_FOUND",
index: "INDEX_NOT_FOUND",
trigger: "TRIGGER_NOT_FOUND",
preset: "PRESET_NOT_FOUND"
};
var RoninError = class extends Error {

@@ -463,63 +469,63 @@ code;

];
var SYSTEM_MODELS = [
{
slug: "model",
identifiers: {
name: "name",
slug: "slug"
},
// This name mimics the `sqlite_schema` table in SQLite.
table: "ronin_schema",
fields: [
{ slug: "name", type: "string" },
{ slug: "pluralName", type: "string" },
{ slug: "slug", type: "string" },
{ slug: "pluralSlug", type: "string" },
{ slug: "idPrefix", type: "string" },
{ slug: "table", type: "string" },
{ slug: "identifiers", type: "group" },
{ slug: "identifiers.name", type: "string" },
{ slug: "identifiers.slug", type: "string" },
// Providing an empty object as a default value allows us to use `json_insert`
// without needing to fall back to an empty object in the insertion statement,
// which makes the statement shorter.
{ slug: "fields", type: "json", defaultValue: "{}" },
{ slug: "indexes", type: "json", defaultValue: "{}" },
{ slug: "triggers", type: "json", defaultValue: "{}" },
{ slug: "presets", type: "json", defaultValue: "{}" }
]
}
];
var addSystemModels = (models) => {
const associativeModels = models.flatMap((model) => {
const addedModels = [];
for (const field of model.fields || []) {
if (field.type === "link" && !field.slug.startsWith("ronin.")) {
const relatedModel = getModelBySlug(models, field.target);
let fieldSlug = relatedModel.slug;
if (field.kind === "many") {
fieldSlug = composeAssociationModelSlug(model, field);
addedModels.push({
pluralSlug: fieldSlug,
slug: fieldSlug,
associationSlug: field.slug,
fields: [
{
slug: "source",
type: "link",
target: model.slug
},
{
slug: "target",
type: "link",
target: relatedModel.slug
}
]
});
}
var ROOT_MODEL = {
slug: "model",
identifiers: {
name: "name",
slug: "slug"
},
// This name mimics the `sqlite_schema` table in SQLite.
table: "ronin_schema",
// Indicates that the model was automatically generated by RONIN.
system: { model: "root" },
fields: [
{ slug: "name", type: "string" },
{ slug: "pluralName", type: "string" },
{ slug: "slug", type: "string" },
{ slug: "pluralSlug", type: "string" },
{ slug: "idPrefix", type: "string" },
{ slug: "table", type: "string" },
{ slug: "identifiers", type: "group" },
{ slug: "identifiers.name", type: "string" },
{ slug: "identifiers.slug", type: "string" },
// Providing an empty object as a default value allows us to use `json_insert`
// without needing to fall back to an empty object in the insertion statement,
// which makes the statement shorter.
{ slug: "fields", type: "json", defaultValue: "{}" },
{ slug: "indexes", type: "json", defaultValue: "{}" },
{ slug: "triggers", type: "json", defaultValue: "{}" },
{ slug: "presets", type: "json", defaultValue: "{}" }
]
};
var getSystemModels = (models, model) => {
const addedModels = [];
for (const field of model.fields || []) {
if (field.type === "link" && !field.slug.startsWith("ronin.")) {
const relatedModel = getModelBySlug(models, field.target);
let fieldSlug = relatedModel.slug;
if (field.kind === "many") {
fieldSlug = composeAssociationModelSlug(model, field);
addedModels.push({
pluralSlug: fieldSlug,
slug: fieldSlug,
system: {
model: model.slug,
associationSlug: field.slug
},
fields: [
{
slug: "source",
type: "link",
target: model.slug
},
{
slug: "target",
type: "link",
target: relatedModel.slug
}
]
});
}
}
return addedModels;
});
return [...SYSTEM_MODELS, ...associativeModels, ...models];
}
return addedModels;
};

@@ -566,3 +572,3 @@ var addDefaultModelPresets = (list, model) => {

const pluralSlug = childModel.pluralSlug;
const presetSlug = childModel.associationSlug || pluralSlug;
const presetSlug = childModel.system?.associationSlug || pluralSlug;
defaultPresets.push({

@@ -623,2 +629,3 @@ instructions: {

if (field.type === "link") {
if (field.kind === "many") return null;
const actions = field.actions || {};

@@ -648,2 +655,14 @@ const targetTable = getModelBySlug(models, field.target).table;

};
var handleSystemModel = (models, dependencyStatements, action, systemModel, newModel) => {
const { system: _, ...systemModelClean } = systemModel;
const query = {
[action]: { model: action === "create" ? systemModelClean : systemModelClean.slug }
};
if (action === "alter" && newModel) {
const { system: _2, ...newModelClean } = newModel;
query.alter.to = newModelClean;
}
const statement = compileQueryInput(query, models, []);
dependencyStatements.push(...statement.dependencies);
};
var transformMetaQuery = (models, dependencyStatements, statementParams, query) => {

@@ -677,6 +696,3 @@ const { queryType } = splitQuery(query);

if (!(modelSlug && slug)) return query;
const tableAction = ["model", "index", "trigger"].includes(entity) ? action.toUpperCase() : "ALTER";
const tableName = convertToSnakeCase(pluralize(modelSlug));
const model = action === "create" && entity === "model" ? null : getModelBySlug(models, modelSlug);
const statement = `${tableAction} TABLE "${tableName}"`;
if (entity === "model") {

@@ -687,3 +703,6 @@ let queryTypeDetails;

const modelWithFields = addDefaultModelFields(newModel, true);
const modelWithPresets = addDefaultModelPresets(models, modelWithFields);
const modelWithPresets = addDefaultModelPresets(
[...models, modelWithFields],
modelWithFields
);
const entities = Object.fromEntries(

@@ -697,3 +716,3 @@ Object.entries(PLURAL_MODEL_ENTITIES).map(([type, pluralType2]) => {

dependencyStatements.push({
statement: `${statement} (${columns.join(", ")})`,
statement: `CREATE TABLE "${modelWithPresets.table}" (${columns.join(", ")})`,
params: []

@@ -707,2 +726,5 @@ });

queryTypeDetails = { to: finalModel };
getSystemModels(models, modelWithPresets).map((systemModel) => {
return handleSystemModel(models, dependencyStatements, "create", systemModel);
});
}

@@ -713,7 +735,6 @@ if (action === "alter" && model) {

const modelWithPresets = addDefaultModelPresets(models, modelWithFields);
const newSlug = modelWithPresets.pluralSlug;
if (newSlug) {
const newTable = convertToSnakeCase(newSlug);
const newTableName = modelWithPresets.table;
if (newTableName) {
dependencyStatements.push({
statement: `${statement} RENAME TO "${newTable}"`,
statement: `ALTER TABLE "${model.table}" RENAME TO "${newTableName}"`,
params: []

@@ -732,4 +753,7 @@ });

models.splice(models.indexOf(model), 1);
dependencyStatements.push({ statement, params: [] });
dependencyStatements.push({ statement: `DROP TABLE "${model.table}"`, params: [] });
queryTypeDetails = { with: { slug } };
models.filter(({ system }) => system?.model === model.slug).map((systemModel) => {
return handleSystemModel(models, dependencyStatements, "drop", systemModel);
});
}

@@ -743,13 +767,32 @@ const queryTypeAction = action === "create" ? "add" : action === "alter" ? "set" : "remove";

}
if (entity === "field" && model) {
const modelBeforeUpdate = structuredClone(model);
const existingModel = model;
const pluralType = PLURAL_MODEL_ENTITIES[entity];
const targetEntityIndex = existingModel[pluralType]?.findIndex(
(entity2) => entity2.slug === slug
);
if ((action === "alter" || action === "drop") && (typeof targetEntityIndex === "undefined" || targetEntityIndex === -1)) {
throw new RoninError({
message: `No ${entity} with slug "${slug}" defined in model "${existingModel.name}".`,
code: MODEL_ENTITY_ERROR_CODES[entity]
});
}
const existingEntity = existingModel[pluralType]?.[targetEntityIndex];
if (entity === "field") {
const statement = `ALTER TABLE "${existingModel.table}"`;
const existingField = existingEntity;
const existingLinkField = existingField?.type === "link" && existingField.kind === "many";
if (action === "create") {
const field2 = jsonValue;
field2.type = field2.type || "string";
dependencyStatements.push({
statement: `${statement} ADD COLUMN ${getFieldStatement(models, model, field2)}`,
params: []
});
const fieldStatement = getFieldStatement(models, existingModel, field2);
if (fieldStatement) {
dependencyStatements.push({
statement: `${statement} ADD COLUMN ${fieldStatement}`,
params: []
});
}
} else if (action === "alter") {
const newSlug = jsonValue?.slug;
if (newSlug) {
if (newSlug && !existingLinkField) {
dependencyStatements.push({

@@ -760,3 +803,3 @@ statement: `${statement} RENAME COLUMN "${slug}" TO "${newSlug}"`,

}
} else if (action === "drop") {
} else if (action === "drop" && !existingLinkField) {
dependencyStatements.push({

@@ -768,7 +811,8 @@ statement: `${statement} DROP COLUMN "${slug}"`,

}
if (entity === "index" && model) {
const statementAction = action.toUpperCase();
if (entity === "index") {
const index = jsonValue;
const indexName = convertToSnakeCase(slug);
const params = [];
let statement2 = `${tableAction}${index?.unique ? " UNIQUE" : ""} INDEX "${indexName}"`;
let statement = `${statementAction}${index?.unique ? " UNIQUE" : ""} INDEX "${indexName}"`;
if (action === "create") {

@@ -778,5 +822,5 @@ const columns = index.fields.map((field2) => {

if ("slug" in field2) {
({ fieldSelector } = getFieldFromModel(model, field2.slug, "to"));
({ fieldSelector } = getFieldFromModel(existingModel, field2.slug, "to"));
} else if ("expression" in field2) {
fieldSelector = parseFieldExpression(model, "to", field2.expression);
fieldSelector = parseFieldExpression(existingModel, "to", field2.expression);
}

@@ -787,14 +831,14 @@ if (field2.collation) fieldSelector += ` COLLATE ${field2.collation}`;

});
statement2 += ` ON "${tableName}" (${columns.join(", ")})`;
statement += ` ON "${existingModel.table}" (${columns.join(", ")})`;
if (index.filter) {
const withStatement = handleWith(models, model, params, index.filter);
statement2 += ` WHERE (${withStatement})`;
const withStatement = handleWith(models, existingModel, params, index.filter);
statement += ` WHERE (${withStatement})`;
}
}
dependencyStatements.push({ statement: statement2, params });
dependencyStatements.push({ statement, params });
}
if (entity === "trigger" && model) {
if (entity === "trigger") {
const triggerName = convertToSnakeCase(slug);
const params = [];
let statement2 = `${tableAction} TRIGGER "${triggerName}"`;
let statement = `${statementAction} TRIGGER "${triggerName}"`;
if (action === "create") {

@@ -812,7 +856,7 @@ const trigger = jsonValue;

const fieldSelectors = trigger.fields.map((field2) => {
return getFieldFromModel(model, field2.slug, "to").fieldSelector;
return getFieldFromModel(existingModel, field2.slug, "to").fieldSelector;
});
statementParts.push(`OF (${fieldSelectors.join(", ")})`);
}
statementParts.push("ON", `"${tableName}"`);
statementParts.push("ON", `"${existingModel.table}"`);
if (trigger.filter || trigger.effects.some((query2) => findInObject(query2, RONIN_MODEL_SYMBOLS.FIELD))) {

@@ -825,3 +869,3 @@ statementParts.push("FOR EACH ROW");

models,
{ ...model, tableAlias },
{ ...existingModel, tableAlias },
params,

@@ -835,3 +879,3 @@ trigger.filter

returning: false,
parentModel: model
parentModel: existingModel
}).main.statement;

@@ -842,7 +886,6 @@ });

if (effectStatements.length > 1) statementParts.push("END");
statement2 += ` ${statementParts.join(" ")}`;
statement += ` ${statementParts.join(" ")}`;
}
dependencyStatements.push({ statement: statement2, params });
dependencyStatements.push({ statement, params });
}
const pluralType = PLURAL_MODEL_ENTITIES[entity];
const field = `${RONIN_MODEL_SYMBOLS.FIELD}${pluralType}`;

@@ -854,2 +897,6 @@ let json;

json = `json_insert(${field}, '$.${slug}', ${value})`;
existingModel[pluralType] = [
...existingModel[pluralType] || [],
jsonValue
];
break;

@@ -860,2 +907,4 @@ }

json = `json_set(${field}, '$.${slug}', json_patch(json_extract(${field}, '$.${slug}'), ${value}))`;
const targetEntity = existingModel[pluralType];
Object.assign(targetEntity[targetEntityIndex], jsonValue);
break;

@@ -865,4 +914,40 @@ }

json = `json_remove(${field}, '$.${slug}')`;
const targetEntity = existingModel[pluralType];
targetEntity.splice(targetEntityIndex, 1);
}
}
const currentSystemModels = models.filter(({ system }) => {
return system?.model === existingModel.slug;
});
const newSystemModels = getSystemModels(models, existingModel);
const matchSystemModels = (oldSystemModel, newSystemModel) => {
const conditions = [
oldSystemModel.system?.model === newSystemModel.system?.model
];
if (oldSystemModel.system?.associationSlug) {
const oldFieldIndex = modelBeforeUpdate?.fields.findIndex((item) => {
return item.slug === newSystemModel.system?.associationSlug;
});
const newFieldIndex = existingModel.fields.findIndex((item) => {
return item.slug === oldSystemModel.system?.associationSlug;
});
conditions.push(oldFieldIndex === newFieldIndex);
}
return conditions.every((condition) => condition === true);
};
for (const systemModel of currentSystemModels) {
const exists = newSystemModels.find(matchSystemModels.bind(null, systemModel));
if (exists) {
if (exists.slug !== systemModel.slug) {
handleSystemModel(models, dependencyStatements, "alter", systemModel, exists);
}
continue;
}
handleSystemModel(models, dependencyStatements, "drop", systemModel);
}
for (const systemModel of newSystemModels) {
const exists = currentSystemModels.find(matchSystemModels.bind(null, systemModel));
if (exists) continue;
handleSystemModel(models, dependencyStatements, "create", systemModel);
}
return {

@@ -1238,3 +1323,10 @@ set: {

// src/utils/index.ts
var compileQueryInput = (query, models, statementParams, options) => {
var compileQueryInput = (defaultQuery, models, statementParams, options) => {
const dependencyStatements = [];
const query = transformMetaQuery(
models,
dependencyStatements,
statementParams,
defaultQuery
);
const parsedQuery = splitQuery(query);

@@ -1245,3 +1337,2 @@ const { queryType, queryModel, queryInstructions } = parsedQuery;

let instructions = formatIdentifiers(model, queryInstructions);
const dependencyStatements = [];
const returning = options?.returning ?? true;

@@ -1398,3 +1489,7 @@ if (instructions && Object.hasOwn(instructions, "for")) {

compileQueries = (queries, models, options) => {
const modelList = addSystemModels(models).map((model) => {
const modelList = [
ROOT_MODEL,
...models.flatMap((model) => getSystemModels(models, model)),
...models
].map((model) => {
return addDefaultModelFields(model, true);

@@ -1408,13 +1503,6 @@ });

for (const query of queries) {
const statementValues = options?.inlineParams ? null : [];
const transformedQuery = transformMetaQuery(
modelListWithPresets,
dependencyStatements,
statementValues,
query
);
const result = compileQueryInput(
transformedQuery,
query,
modelListWithPresets,
statementValues
options?.inlineParams ? null : []
);

@@ -1421,0 +1509,0 @@ dependencyStatements.push(...result.dependencies);

{
"name": "@ronin/compiler",
"version": "0.9.0",
"version": "0.10.0-leo-ron-1083-experimental-206",
"type": "module",

@@ -5,0 +5,0 @@ "description": "Compiles RONIN queries to SQL statements.",

@@ -55,2 +55,5 @@ # RONIN Compiler

// [{
// statement: 'CREATE TABLE "accounts" ...',
// params: []
// }, {
// statement: 'SELECT * FROM "accounts"',

@@ -57,0 +60,0 @@ // params: [],

Sorry, the diff of this file is too big to display

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