@ronin/compiler
Advanced tools
Comparing version 0.5.0 to 0.5.1
@@ -320,3 +320,3 @@ // src/utils/helpers.ts | ||
var composeMetaSchemaSlug = (suffix) => convertToCamelCase(`ronin_${suffix}`); | ||
var composeAssociationSchemaSlug = (schema, field) => composeMetaSchemaSlug(`${schema.pluralSlug}_${field.slug}`); | ||
var composeAssociationSchemaSlug = (schema, field) => composeMetaSchemaSlug(`${schema.slug}_${field.slug}`); | ||
var getFieldSelector = (field, fieldPath, rootTable) => { | ||
@@ -356,2 +356,49 @@ const symbol = rootTable?.startsWith(RONIN_SCHEMA_SYMBOLS.FIELD) ? `${rootTable.replace(RONIN_SCHEMA_SYMBOLS.FIELD, "").slice(0, -1)}.` : ""; | ||
}; | ||
var slugToName = (slug) => { | ||
const name = slug.replace(/([a-z])([A-Z])/g, "$1 $2"); | ||
return title(name); | ||
}; | ||
var VOWELS = ["a", "e", "i", "o", "u"]; | ||
var pluralize = (word) => { | ||
const lastLetter = word.slice(-1).toLowerCase(); | ||
const secondLastLetter = word.slice(-2, -1).toLowerCase(); | ||
if (lastLetter === "y" && !VOWELS.includes(secondLastLetter)) { | ||
return `${word.slice(0, -1)}ies`; | ||
} | ||
if (lastLetter === "s" || word.slice(-2).toLowerCase() === "ch" || word.slice(-2).toLowerCase() === "sh" || word.slice(-2).toLowerCase() === "ex") { | ||
return `${word}es`; | ||
} | ||
return `${word}s`; | ||
}; | ||
var schemaSettings = [ | ||
["pluralSlug", "slug", pluralize], | ||
["name", "slug", slugToName], | ||
["pluralName", "pluralSlug", slugToName], | ||
["idPrefix", "slug", (slug) => slug.slice(0, 3)] | ||
]; | ||
var addDefaultSchemaFields = (schema, isNew) => { | ||
const copiedSchema = { ...schema }; | ||
for (const [setting, base, generator] of schemaSettings) { | ||
if (copiedSchema[setting] || !copiedSchema[base]) continue; | ||
copiedSchema[setting] = generator(copiedSchema[base]); | ||
} | ||
const newFields = copiedSchema.fields || []; | ||
if (isNew || newFields.length > 0) { | ||
if (!copiedSchema.identifiers) copiedSchema.identifiers = {}; | ||
if (!copiedSchema.identifiers.name) { | ||
const suitableField = newFields.find( | ||
(field) => field.type === "string" && field.required === true && ["name"].includes(field.slug) | ||
); | ||
copiedSchema.identifiers.name = suitableField?.slug || "id"; | ||
} | ||
if (!copiedSchema.identifiers.slug) { | ||
const suitableField = newFields.find( | ||
(field) => field.type === "string" && field.unique === true && field.required === true && ["slug", "handle"].includes(field.slug) | ||
); | ||
copiedSchema.identifiers.slug = suitableField?.slug || "id"; | ||
} | ||
copiedSchema.fields = [...SYSTEM_FIELDS, ...newFields]; | ||
} | ||
return copiedSchema; | ||
}; | ||
var SYSTEM_FIELDS = [ | ||
@@ -397,6 +444,3 @@ { | ||
{ | ||
name: "Schema", | ||
pluralName: "Schemas", | ||
slug: "schema", | ||
pluralSlug: "schemas", | ||
identifiers: { | ||
@@ -407,3 +451,2 @@ name: "name", | ||
fields: [ | ||
...SYSTEM_FIELDS, | ||
{ slug: "name", type: "string" }, | ||
@@ -419,10 +462,9 @@ { slug: "pluralName", type: "string" }, | ||
{ slug: "indexes", type: "json" }, | ||
{ slug: "triggers", type: "json" } | ||
{ slug: "triggers", type: "json" }, | ||
{ slug: "including", type: "json" }, | ||
{ slug: "for", type: "json" } | ||
] | ||
}, | ||
{ | ||
name: "Field", | ||
pluralName: "Fields", | ||
slug: "field", | ||
pluralSlug: "fields", | ||
identifiers: { | ||
@@ -433,3 +475,2 @@ name: "name", | ||
fields: [ | ||
...SYSTEM_FIELDS, | ||
{ slug: "name", type: "string" }, | ||
@@ -457,6 +498,3 @@ { slug: "slug", type: "string", required: true }, | ||
{ | ||
name: "Index", | ||
pluralName: "Indexes", | ||
slug: "index", | ||
pluralSlug: "indexes", | ||
identifiers: { | ||
@@ -467,3 +505,2 @@ name: "slug", | ||
fields: [ | ||
...SYSTEM_FIELDS, | ||
{ slug: "slug", type: "string", required: true }, | ||
@@ -481,6 +518,3 @@ { | ||
{ | ||
name: "Trigger", | ||
pluralName: "Triggers", | ||
slug: "trigger", | ||
pluralSlug: "triggers", | ||
identifiers: { | ||
@@ -491,3 +525,2 @@ name: "slug", | ||
fields: [ | ||
...SYSTEM_FIELDS, | ||
{ slug: "slug", type: "string", required: true }, | ||
@@ -500,3 +533,3 @@ { slug: "schema", type: "reference", target: { slug: "schema" }, required: true }, | ||
} | ||
]; | ||
].map((schema) => addDefaultSchemaFields(schema, true)); | ||
var SYSTEM_SCHEMA_SLUGS = SYSTEM_SCHEMAS.flatMap(({ slug, pluralSlug }) => [ | ||
@@ -506,31 +539,14 @@ slug, | ||
]); | ||
var prepareSchema = (schema) => { | ||
const copiedSchema = { ...schema }; | ||
if (!copiedSchema.pluralSlug) copiedSchema.pluralSlug = pluralize(copiedSchema.slug); | ||
if (!copiedSchema.name) copiedSchema.name = slugToName(copiedSchema.slug); | ||
if (!copiedSchema.pluralName) | ||
copiedSchema.pluralName = slugToName(copiedSchema.pluralSlug); | ||
if (!copiedSchema.idPrefix) copiedSchema.idPrefix = copiedSchema.slug.slice(0, 3); | ||
if (!copiedSchema.identifiers) copiedSchema.identifiers = {}; | ||
if (!copiedSchema.identifiers.name) copiedSchema.identifiers.name = "id"; | ||
if (!copiedSchema.identifiers.slug) copiedSchema.identifiers.slug = "id"; | ||
return copiedSchema; | ||
}; | ||
var addSystemSchemas = (schemas) => { | ||
const list = [...SYSTEM_SCHEMAS, ...schemas].map(prepareSchema); | ||
for (const schema of list) { | ||
const defaultIncluding = {}; | ||
const associativeSchemas = schemas.flatMap((schema) => { | ||
const addedSchemas = []; | ||
for (const field of schema.fields || []) { | ||
if (field.type === "reference" && !field.slug.startsWith("ronin.")) { | ||
const relatedSchema = getSchemaBySlug(list, field.target.slug); | ||
const relatedSchema = getSchemaBySlug(schemas, field.target.slug); | ||
let fieldSlug = relatedSchema.slug; | ||
if (field.kind === "many") { | ||
fieldSlug = composeAssociationSchemaSlug(schema, field); | ||
list.push({ | ||
addedSchemas.push({ | ||
pluralSlug: fieldSlug, | ||
slug: fieldSlug, | ||
identifiers: { | ||
name: "id", | ||
slug: "id" | ||
}, | ||
fields: [ | ||
@@ -540,3 +556,3 @@ { | ||
type: "reference", | ||
target: schema | ||
target: { slug: schema.slug } | ||
}, | ||
@@ -546,3 +562,3 @@ { | ||
type: "reference", | ||
target: relatedSchema | ||
target: { slug: relatedSchema.slug } | ||
} | ||
@@ -552,33 +568,54 @@ ] | ||
} | ||
defaultIncluding[field.slug] = { | ||
get: { | ||
[fieldSlug]: { | ||
with: { | ||
// Compare the `id` field of the related schema to the reference field on | ||
// the root schema (`field.slug`). | ||
id: `${RONIN_SCHEMA_SYMBOLS.FIELD}${field.slug}` | ||
} | ||
} | ||
} | ||
return addedSchemas; | ||
}); | ||
return [...SYSTEM_SCHEMAS, ...associativeSchemas, ...schemas]; | ||
}; | ||
var addDefaultSchemaShortcuts = (list, schema) => { | ||
const defaultIncluding = {}; | ||
for (const field of schema.fields || []) { | ||
if (field.type === "reference" && !field.slug.startsWith("ronin.")) { | ||
const relatedSchema = getSchemaBySlug(list, field.target.slug); | ||
let fieldSlug = relatedSchema.slug; | ||
if (field.kind === "many") { | ||
fieldSlug = composeAssociationSchemaSlug(schema, field); | ||
} | ||
defaultIncluding[field.slug] = { | ||
get: { | ||
[fieldSlug]: { | ||
with: { | ||
// Compare the `id` field of the related schema to the reference field on | ||
// the root schema (`field.slug`). | ||
id: `${RONIN_SCHEMA_SYMBOLS.FIELD}${field.slug}` | ||
} | ||
} | ||
}; | ||
const relatedSchemaToModify = getSchemaBySlug(list, field.target.slug); | ||
if (!relatedSchemaToModify) throw new Error("Missing related schema"); | ||
relatedSchemaToModify.including = { | ||
[schema.pluralSlug]: { | ||
get: { | ||
[schema.pluralSlug]: { | ||
with: { | ||
[field.slug]: `${RONIN_SCHEMA_SYMBOLS.FIELD}id` | ||
} | ||
} | ||
} | ||
}, | ||
...relatedSchemaToModify.including | ||
}; | ||
} | ||
}; | ||
} | ||
} | ||
const childSchemas = list.map((subSchema) => { | ||
const field = subSchema.fields?.find((field2) => { | ||
return field2.type === "reference" && field2.target.slug === schema.slug; | ||
}); | ||
if (!field) return null; | ||
return { schema: subSchema, field }; | ||
}).filter((match) => match !== null); | ||
for (const childMatch of childSchemas) { | ||
const { schema: childSchema, field: childField } = childMatch; | ||
const pluralSlug = childSchema.pluralSlug; | ||
defaultIncluding[pluralSlug] = { | ||
get: { | ||
[pluralSlug]: { | ||
with: { | ||
[childField.slug]: `${RONIN_SCHEMA_SYMBOLS.FIELD}id` | ||
} | ||
} | ||
} | ||
} | ||
schema.fields = [...SYSTEM_FIELDS, ...schema.fields || []]; | ||
}; | ||
} | ||
if (Object.keys(defaultIncluding).length > 0) { | ||
schema.including = { ...defaultIncluding, ...schema.including }; | ||
} | ||
return list; | ||
return schema; | ||
}; | ||
@@ -731,12 +768,19 @@ var mappedInstructions = { | ||
} | ||
let statement = `${tableAction} TABLE "${tableName}"`; | ||
const statement = `${tableAction} TABLE "${tableName}"`; | ||
if (kind === "schemas") { | ||
const providedFields = instructionList?.fields || []; | ||
const fields = [...SYSTEM_FIELDS, ...providedFields]; | ||
if (queryType === "create" || queryType === "set") { | ||
queryInstructions.to = prepareSchema(queryInstructions.to); | ||
const schemaWithFields = addDefaultSchemaFields( | ||
queryInstructions.to, | ||
queryType === "create" | ||
); | ||
const schemaWithShortcuts = addDefaultSchemaShortcuts(schemas, schemaWithFields); | ||
queryInstructions.to = schemaWithShortcuts; | ||
} | ||
if (queryType === "create") { | ||
const { fields } = queryInstructions.to; | ||
const columns = fields.map(getFieldStatement).filter(Boolean); | ||
statement += ` (${columns.join(", ")})`; | ||
dependencyStatements.push({ | ||
statement: `${statement} (${columns.join(", ")})`, | ||
params: [] | ||
}); | ||
schemas.push(queryInstructions.to); | ||
@@ -747,3 +791,6 @@ } else if (queryType === "set") { | ||
const newTable = convertToSnakeCase(newSlug); | ||
statement += ` RENAME TO "${newTable}"`; | ||
dependencyStatements.push({ | ||
statement: `${statement} RENAME TO "${newTable}"`, | ||
params: [] | ||
}); | ||
} | ||
@@ -753,4 +800,4 @@ Object.assign(targetSchema, queryInstructions.to); | ||
schemas.splice(schemas.indexOf(targetSchema), 1); | ||
dependencyStatements.push({ statement, params: [] }); | ||
} | ||
dependencyStatements.push({ statement, params: [] }); | ||
return queryInstructions; | ||
@@ -767,31 +814,23 @@ } | ||
} | ||
statement += ` ADD COLUMN ${getFieldStatement(instructionList)}`; | ||
dependencyStatements.push({ | ||
statement: `${statement} ADD COLUMN ${getFieldStatement(instructionList)}`, | ||
params: [] | ||
}); | ||
} else if (queryType === "set") { | ||
const newSlug = queryInstructions.to?.slug; | ||
if (newSlug) { | ||
statement += ` RENAME COLUMN "${slug}" TO "${newSlug}"`; | ||
dependencyStatements.push({ | ||
statement: `${statement} RENAME COLUMN "${slug}" TO "${newSlug}"`, | ||
params: [] | ||
}); | ||
} | ||
} else if (queryType === "drop") { | ||
statement += ` DROP COLUMN "${slug}"`; | ||
dependencyStatements.push({ | ||
statement: `${statement} DROP COLUMN "${slug}"`, | ||
params: [] | ||
}); | ||
} | ||
dependencyStatements.push({ statement, params: [] }); | ||
} | ||
return queryInstructions; | ||
}; | ||
var slugToName = (slug) => { | ||
const name = slug.replace(/([a-z])([A-Z])/g, "$1 $2"); | ||
return title(name); | ||
}; | ||
var VOWELS = ["a", "e", "i", "o", "u"]; | ||
var pluralize = (word) => { | ||
const lastLetter = word.slice(-1).toLowerCase(); | ||
const secondLastLetter = word.slice(-2, -1).toLowerCase(); | ||
if (lastLetter === "y" && !VOWELS.includes(secondLastLetter)) { | ||
return `${word.slice(0, -1)}ies`; | ||
} | ||
if (lastLetter === "s" || word.slice(-2).toLowerCase() === "ch" || word.slice(-2).toLowerCase() === "sh" || word.slice(-2).toLowerCase() === "ex") { | ||
return `${word}es`; | ||
} | ||
return `${word}s`; | ||
}; | ||
@@ -805,4 +844,3 @@ // src/instructions/before-after.ts | ||
message: "The `before` or `after` instruction must not be empty.", | ||
code: "MISSING_INSTRUCTION", | ||
queries: null | ||
code: "MISSING_INSTRUCTION" | ||
}); | ||
@@ -813,6 +851,14 @@ } | ||
message: "The `before` and `after` instructions cannot co-exist. Choose one.", | ||
code: "MUTUALLY_EXCLUSIVE_INSTRUCTIONS", | ||
queries: null | ||
code: "MUTUALLY_EXCLUSIVE_INSTRUCTIONS" | ||
}); | ||
} | ||
if (!instructions.limitedTo) { | ||
let message = "When providing a pagination cursor in the `before` or `after`"; | ||
message += " instruction, a `limitedTo` instruction must be provided as well, to"; | ||
message += " define the page size."; | ||
throw new RoninError({ | ||
message, | ||
code: "MISSING_INSTRUCTION" | ||
}); | ||
} | ||
const { ascending = [], descending = [] } = instructions.orderedBy || {}; | ||
@@ -975,5 +1021,6 @@ const clause = instructions.with ? "AND " : ""; | ||
var handleLimitedTo = (single, instruction) => { | ||
const pageSize = instruction || 100; | ||
const finalPageSize = pageSize + 1; | ||
return `LIMIT ${single ? "1" : finalPageSize} `; | ||
let amount; | ||
if (instruction) amount = instruction + 1; | ||
if (single) amount = 1; | ||
return `LIMIT ${amount} `; | ||
}; | ||
@@ -1242,3 +1289,3 @@ | ||
} | ||
if ((queryType === "get" || queryType === "count") && !single) { | ||
if ((queryType === "get" || queryType === "count") && !single && instructions?.limitedTo) { | ||
instructions = instructions || {}; | ||
@@ -1270,3 +1317,4 @@ instructions.orderedBy = instructions.orderedBy || {}; | ||
with: instructions.with, | ||
orderedBy: instructions.orderedBy | ||
orderedBy: instructions.orderedBy, | ||
limitedTo: instructions.limitedTo | ||
}, | ||
@@ -1292,3 +1340,3 @@ isJoining ? table : void 0 | ||
} | ||
if (queryType === "get" && !isJoiningMultipleRows) { | ||
if (queryType === "get" && !isJoiningMultipleRows && (single || instructions?.limitedTo)) { | ||
statement += handleLimitedTo(single, instructions?.limitedTo); | ||
@@ -1312,3 +1360,8 @@ } | ||
var compileQueries = (queries, schemas, options) => { | ||
const schemaList = addSystemSchemas(schemas); | ||
const schemaList = addSystemSchemas(schemas).map((schema) => { | ||
return addDefaultSchemaFields(schema, true); | ||
}); | ||
const schemaListWithShortcuts = schemaList.map((schema) => { | ||
return addDefaultSchemaShortcuts(schemaList, schema); | ||
}); | ||
const dependencyStatements = []; | ||
@@ -1319,3 +1372,3 @@ const mainStatements = []; | ||
query, | ||
schemaList, | ||
schemaListWithShortcuts, | ||
options?.inlineValues ? null : [] | ||
@@ -1322,0 +1375,0 @@ ); |
{ | ||
"name": "@ronin/compiler", | ||
"version": "0.5.0", | ||
"version": "0.5.1", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "description": "Compiles RONIN queries to SQL statements.", |
@@ -62,3 +62,3 @@ # RONIN Compiler | ||
// [{ | ||
// statement: 'SELECT * FROM "accounts" ORDER BY "ronin.createdAt" DESC LIMIT 101', | ||
// statement: 'SELECT * FROM "accounts"', | ||
// params: [], | ||
@@ -65,0 +65,0 @@ // returning: true, |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
372199
6101
0