@ronin/compiler 0.8.4 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -5985,4 +5985,4 @@ declare const compileQueries: (queries: Array<Query>, models: Array<PublicModel>
5985
5985
  inlineParams?: boolean;
5986
5986
  }) => Array<Statement>;
5987
5987
 
5988
- export { type PublicModel as Model, type ModelField, type ModelIndex, type ModelTrigger, type Query, type Statement, compileQueries };
5988
+ export { type PublicModel as Model, type ModelField, type ModelIndex, type ModelPreset, type ModelTrigger, type Query, type Statement, compileQueries };
package/dist/index.js CHANGED
@@ -318,151 +318,6 @@ var handleWith = (models, model, statementParams, instruction, parentModel) => {
318
318
  return `(${subStatement})`;
319
319
  };
320
320
 
321
- // src/utils/meta.ts
322
- var PLURAL_MODEL_ENTITIES = {
323
- field: "fields",
324
- index: "indexes",
325
- trigger: "triggers",
326
- preset: "presets"
327
- };
328
- var transformMetaQuery = (models, dependencyStatements, statementParams, query) => {
329
- if (query.create) {
330
- const init = query.create.model;
331
- const details = "to" in query.create ? { slug: init, ...query.create.to } : init;
332
- const modelWithFields = addDefaultModelFields(details, true);
333
- const modelWithPresets = addDefaultModelPresets(models, modelWithFields);
334
- const instructions = {
335
- to: modelWithPresets
336
- };
337
- addModelQueries(models, dependencyStatements, {
338
- queryType: "add",
339
- queryModel: "model",
340
- queryInstructions: instructions
341
- });
342
- return {
343
- add: {
344
- model: instructions
345
- }
346
- };
347
- }
348
- if (query.drop) {
349
- const slug = query.drop.model;
350
- const instructions = {
351
- with: { slug }
352
- };
353
- addModelQueries(models, dependencyStatements, {
354
- queryType: "remove",
355
- queryModel: "model",
356
- queryInstructions: instructions
357
- });
358
- return {
359
- remove: {
360
- model: instructions
361
- }
362
- };
363
- }
364
- if (query.alter) {
365
- const slug = query.alter.model;
366
- if ("to" in query.alter) {
367
- const modelWithFields = addDefaultModelFields(query.alter.to, false);
368
- const modelWithPresets = addDefaultModelPresets(models, modelWithFields);
369
- const instructions = {
370
- with: { slug },
371
- to: modelWithPresets
372
- };
373
- addModelQueries(models, dependencyStatements, {
374
- queryType: "set",
375
- queryModel: "model",
376
- queryInstructions: instructions
377
- });
378
- return {
379
- set: {
380
- model: instructions
381
- }
382
- };
383
- }
384
- if ("create" in query.alter) {
385
- const type2 = Object.keys(query.alter.create)[0];
386
- const pluralType2 = PLURAL_MODEL_ENTITIES[type2];
387
- const item = query.alter.create[type2];
388
- const completeItem = { slug: item.slug || `${type2}Slug`, ...item };
389
- addModelQueries(models, dependencyStatements, {
390
- queryType: "add",
391
- queryModel: type2,
392
- queryInstructions: {
393
- to: {
394
- model: { slug },
395
- ...completeItem
396
- }
397
- }
398
- });
399
- const value = prepareStatementValue(statementParams, completeItem);
400
- const json2 = `json_insert(${RONIN_MODEL_SYMBOLS.FIELD}${pluralType2}, '$.${completeItem.slug}', ${value})`;
401
- const expression2 = { [RONIN_MODEL_SYMBOLS.EXPRESSION]: json2 };
402
- return {
403
- set: {
404
- model: {
405
- with: { slug },
406
- to: {
407
- [pluralType2]: expression2
408
- }
409
- }
410
- }
411
- };
412
- }
413
- if ("alter" in query.alter) {
414
- const type2 = Object.keys(query.alter.alter)[0];
415
- const pluralType2 = PLURAL_MODEL_ENTITIES[type2];
416
- const itemSlug2 = query.alter.alter[type2];
417
- const newItem = query.alter.alter.to;
418
- addModelQueries(models, dependencyStatements, {
419
- queryType: "set",
420
- queryModel: type2,
421
- queryInstructions: {
422
- with: { model: { slug }, slug: itemSlug2 },
423
- to: newItem
424
- }
425
- });
426
- const value = prepareStatementValue(statementParams, newItem);
427
- const json2 = `json_patch(${RONIN_MODEL_SYMBOLS.FIELD}${pluralType2}, '$.${itemSlug2}', ${value})`;
428
- const expression2 = { [RONIN_MODEL_SYMBOLS.EXPRESSION]: json2 };
429
- return {
430
- set: {
431
- model: {
432
- with: { slug },
433
- to: {
434
- [pluralType2]: expression2
435
- }
436
- }
437
- }
438
- };
439
- }
440
- const type = Object.keys(query.alter.drop)[0];
441
- const pluralType = PLURAL_MODEL_ENTITIES[type];
442
- const itemSlug = query.alter.drop[type];
443
- addModelQueries(models, dependencyStatements, {
444
- queryType: "remove",
445
- queryModel: type,
446
- queryInstructions: {
447
- with: { model: { slug }, slug: itemSlug }
448
- }
449
- });
450
- const json = `json_insert(${RONIN_MODEL_SYMBOLS.FIELD}${pluralType}, '$.${itemSlug}')`;
451
- const expression = { [RONIN_MODEL_SYMBOLS.EXPRESSION]: json };
452
- return {
453
- set: {
454
- model: {
455
- with: { slug },
456
- to: {
457
- [pluralType]: expression
458
- }
459
- }
460
- }
461
- };
462
- }
463
- return query;
464
- };
465
-
466
321
  // src/utils/model.ts
467
322
  import title from "title";
468
323
  var getModelBySlug = (models, slug) => {
@@ -732,11 +587,6 @@ var addDefaultModelPresets = (list, model) => {
732
587
  }
733
588
  return model;
734
589
  };
735
- var mappedInstructions = {
736
- add: "to",
737
- set: "with",
738
- remove: "with"
739
- };
740
590
  var typesInSQLite = {
741
591
  link: "TEXT",
742
592
  string: "TEXT",
@@ -777,117 +627,177 @@ var getFieldStatement = (models, model, field) => {
777
627
  }
778
628
  return statement;
779
629
  };
780
- var addModelQueries = (models, dependencyStatements, queryDetails) => {
781
- const { queryType, queryModel, queryInstructions } = queryDetails;
782
- if (!["add", "set", "remove"].includes(queryType)) return;
783
- if (!["model", "field", "index", "trigger", "preset"].includes(queryModel)) return;
784
- const instructionName = mappedInstructions[queryType];
785
- const instructionList = queryInstructions[instructionName];
786
- let tableAction = "ALTER";
787
- let queryTypeReadable = null;
788
- switch (queryType) {
789
- case "add": {
790
- if (queryModel === "model" || queryModel === "index" || queryModel === "trigger") {
791
- tableAction = "CREATE";
630
+ var PLURAL_MODEL_ENTITIES = {
631
+ field: "fields",
632
+ index: "indexes",
633
+ trigger: "triggers",
634
+ preset: "presets"
635
+ };
636
+ var transformMetaQuery = (models, dependencyStatements, statementParams, query) => {
637
+ const { queryType } = splitQuery(query);
638
+ const subAltering = query.alter && !("to" in query.alter);
639
+ const action = subAltering && query.alter ? Object.keys(query.alter).filter((key) => key !== "model")[0] : queryType;
640
+ const actionReadable = action === "create" ? "creating" : action === "alter" ? "altering" : "dropping";
641
+ const entity = subAltering && query.alter ? Object.keys(query.alter[action])[0] : "model";
642
+ let slug = entity === "model" && action === "create" ? null : query[queryType].model;
643
+ let modelSlug = slug;
644
+ let jsonValue;
645
+ if (query.create) {
646
+ const init = query.create.model;
647
+ jsonValue = "to" in query.create ? { slug: init, ...query.create.to } : init;
648
+ slug = modelSlug = jsonValue.slug;
649
+ }
650
+ if (query.alter) {
651
+ if ("to" in query.alter) {
652
+ jsonValue = query.alter.to;
653
+ } else {
654
+ slug = query.alter[action][entity];
655
+ if ("create" in query.alter) {
656
+ const item = query.alter.create[entity];
657
+ slug = item.slug || `${entity}Slug`;
658
+ jsonValue = { slug, ...item };
792
659
  }
793
- queryTypeReadable = "creating";
794
- break;
660
+ if ("alter" in query.alter) jsonValue = query.alter.alter.to;
795
661
  }
796
- case "set": {
797
- if (queryModel === "model") tableAction = "ALTER";
798
- queryTypeReadable = "updating";
799
- break;
662
+ }
663
+ if (!(modelSlug && slug)) return query;
664
+ const tableAction = ["model", "index", "trigger"].includes(entity) ? action.toUpperCase() : "ALTER";
665
+ const tableName = convertToSnakeCase(pluralize(modelSlug));
666
+ const model = action === "create" && entity === "model" ? null : getModelBySlug(models, modelSlug);
667
+ const statement = `${tableAction} TABLE "${tableName}"`;
668
+ if (entity === "model") {
669
+ let queryTypeDetails;
670
+ if (action === "create") {
671
+ const newModel = jsonValue;
672
+ const modelWithFields = addDefaultModelFields(newModel, true);
673
+ const modelWithPresets = addDefaultModelPresets(models, modelWithFields);
674
+ const { fields } = modelWithPresets;
675
+ const columns = fields.map((field) => getFieldStatement(models, modelWithPresets, field)).filter(Boolean);
676
+ dependencyStatements.push({
677
+ statement: `${statement} (${columns.join(", ")})`,
678
+ params: []
679
+ });
680
+ models.push(modelWithPresets);
681
+ queryTypeDetails = { to: modelWithPresets };
800
682
  }
801
- case "remove": {
802
- if (queryModel === "model" || queryModel === "index" || queryModel === "trigger") {
803
- tableAction = "DROP";
683
+ if (action === "alter" && model) {
684
+ const newModel = jsonValue;
685
+ const modelWithFields = addDefaultModelFields(newModel, false);
686
+ const modelWithPresets = addDefaultModelPresets(models, modelWithFields);
687
+ const newSlug = modelWithPresets.pluralSlug;
688
+ if (newSlug) {
689
+ const newTable = convertToSnakeCase(newSlug);
690
+ dependencyStatements.push({
691
+ statement: `${statement} RENAME TO "${newTable}"`,
692
+ params: []
693
+ });
804
694
  }
805
- queryTypeReadable = "deleting";
806
- break;
695
+ Object.assign(model, modelWithPresets);
696
+ queryTypeDetails = {
697
+ with: {
698
+ slug
699
+ },
700
+ to: modelWithPresets
701
+ };
702
+ }
703
+ if (action === "drop" && model) {
704
+ models.splice(models.indexOf(model), 1);
705
+ dependencyStatements.push({ statement, params: [] });
706
+ queryTypeDetails = { with: { slug } };
707
+ }
708
+ const queryTypeAction = action === "create" ? "add" : action === "alter" ? "set" : "remove";
709
+ return {
710
+ [queryTypeAction]: {
711
+ model: queryTypeDetails
712
+ }
713
+ };
714
+ }
715
+ if (entity === "field" && model) {
716
+ if (action === "create") {
717
+ const field = jsonValue;
718
+ field.type = field.type || "string";
719
+ dependencyStatements.push({
720
+ statement: `${statement} ADD COLUMN ${getFieldStatement(models, model, field)}`,
721
+ params: []
722
+ });
723
+ } else if (action === "alter") {
724
+ const newSlug = jsonValue?.slug;
725
+ if (newSlug) {
726
+ dependencyStatements.push({
727
+ statement: `${statement} RENAME COLUMN "${slug}" TO "${newSlug}"`,
728
+ params: []
729
+ });
730
+ }
731
+ } else if (action === "drop") {
732
+ dependencyStatements.push({
733
+ statement: `${statement} DROP COLUMN "${slug}"`,
734
+ params: []
735
+ });
807
736
  }
808
737
  }
809
- const slug = instructionList?.slug?.being || instructionList?.slug;
810
- const modelInstruction = instructionList?.model;
811
- const modelSlug = modelInstruction?.slug?.being || modelInstruction?.slug;
812
- const usableSlug = queryModel === "model" ? slug : modelSlug;
813
- const tableName = convertToSnakeCase(pluralize(usableSlug));
814
- const targetModel = queryModel === "model" && queryType === "add" ? null : getModelBySlug(models, usableSlug);
815
- if (queryModel === "index") {
738
+ if (entity === "index" && model) {
739
+ const index = jsonValue;
816
740
  const indexName = convertToSnakeCase(slug);
817
- const unique = instructionList?.unique;
818
- const filterQuery = instructionList?.filter;
819
- const fields = instructionList?.fields;
820
741
  const params = [];
821
- let statement2 = `${tableAction}${unique ? " UNIQUE" : ""} INDEX "${indexName}"`;
822
- if (queryType === "add") {
823
- const model = targetModel;
824
- const columns = fields.map((field) => {
742
+ let statement2 = `${tableAction}${index?.unique ? " UNIQUE" : ""} INDEX "${indexName}"`;
743
+ if (action === "create") {
744
+ const columns = index.fields.map((field) => {
825
745
  let fieldSelector = "";
826
746
  if ("slug" in field) {
827
747
  ({ fieldSelector } = getFieldFromModel(model, field.slug, "to"));
828
748
  } else if ("expression" in field) {
829
- fieldSelector = parseFieldExpression(model, "to", field.expression, model);
749
+ fieldSelector = parseFieldExpression(model, "to", field.expression);
830
750
  }
831
751
  if (field.collation) fieldSelector += ` COLLATE ${field.collation}`;
832
752
  if (field.order) fieldSelector += ` ${field.order}`;
833
753
  return fieldSelector;
834
754
  });
835
755
  statement2 += ` ON "${tableName}" (${columns.join(", ")})`;
836
- if (filterQuery) {
837
- const withStatement = handleWith(
838
- models,
839
- targetModel,
840
- params,
841
- filterQuery
842
- );
756
+ if (index.filter) {
757
+ const withStatement = handleWith(models, model, params, index.filter);
843
758
  statement2 += ` WHERE (${withStatement})`;
844
759
  }
845
760
  }
846
761
  dependencyStatements.push({ statement: statement2, params });
847
- return;
848
762
  }
849
- if (queryModel === "trigger") {
763
+ if (entity === "trigger" && model) {
850
764
  const triggerName = convertToSnakeCase(slug);
851
765
  const params = [];
852
766
  let statement2 = `${tableAction} TRIGGER "${triggerName}"`;
853
- if (queryType === "add") {
854
- const currentModel = targetModel;
855
- const { when, action } = instructionList;
856
- const statementParts = [`${when} ${action}`];
857
- const effectQueries = instructionList?.effects;
858
- const filterQuery = instructionList?.filter;
859
- const fields = instructionList?.fields;
860
- if (fields) {
861
- if (action !== "UPDATE") {
767
+ if (action === "create") {
768
+ const trigger = jsonValue;
769
+ const statementParts = [`${trigger.when} ${trigger.action}`];
770
+ if (trigger.fields) {
771
+ if (trigger.action !== "UPDATE") {
862
772
  throw new RoninError({
863
- message: `When ${queryTypeReadable} ${PLURAL_MODEL_ENTITIES[queryModel]}, targeting specific fields requires the \`UPDATE\` action.`,
773
+ message: `When ${actionReadable} ${PLURAL_MODEL_ENTITIES[entity]}, targeting specific fields requires the \`UPDATE\` action.`,
864
774
  code: "INVALID_MODEL_VALUE",
865
775
  fields: ["action"]
866
776
  });
867
777
  }
868
- const fieldSelectors = fields.map((field) => {
869
- return getFieldFromModel(currentModel, field.slug, "to").fieldSelector;
778
+ const fieldSelectors = trigger.fields.map((field) => {
779
+ return getFieldFromModel(model, field.slug, "to").fieldSelector;
870
780
  });
871
781
  statementParts.push(`OF (${fieldSelectors.join(", ")})`);
872
782
  }
873
783
  statementParts.push("ON", `"${tableName}"`);
874
- if (filterQuery || effectQueries.some((query) => findInObject(query, RONIN_MODEL_SYMBOLS.FIELD))) {
784
+ if (trigger.filter || trigger.effects.some((query2) => findInObject(query2, RONIN_MODEL_SYMBOLS.FIELD))) {
875
785
  statementParts.push("FOR EACH ROW");
876
786
  }
877
- if (filterQuery) {
878
- const tableAlias = action === "DELETE" ? RONIN_MODEL_SYMBOLS.FIELD_PARENT_OLD : RONIN_MODEL_SYMBOLS.FIELD_PARENT_NEW;
787
+ if (trigger.filter) {
788
+ const tableAlias = trigger.action === "DELETE" ? RONIN_MODEL_SYMBOLS.FIELD_PARENT_OLD : RONIN_MODEL_SYMBOLS.FIELD_PARENT_NEW;
879
789
  const withStatement = handleWith(
880
790
  models,
881
- { ...currentModel, tableAlias },
791
+ { ...model, tableAlias },
882
792
  params,
883
- filterQuery
793
+ trigger.filter
884
794
  );
885
795
  statementParts.push("WHEN", `(${withStatement})`);
886
796
  }
887
- const effectStatements = effectQueries.map((effectQuery) => {
797
+ const effectStatements = trigger.effects.map((effectQuery) => {
888
798
  return compileQueryInput(effectQuery, models, params, {
889
799
  returning: false,
890
- parentModel: currentModel
800
+ parentModel: model
891
801
  }).main.statement;
892
802
  });
893
803
  if (effectStatements.length > 1) statementParts.push("BEGIN");
@@ -896,57 +806,22 @@ var addModelQueries = (models, dependencyStatements, queryDetails) => {
896
806
  statement2 += ` ${statementParts.join(" ")}`;
897
807
  }
898
808
  dependencyStatements.push({ statement: statement2, params });
899
- return;
900
- }
901
- const statement = `${tableAction} TABLE "${tableName}"`;
902
- if (queryModel === "model") {
903
- if (queryType === "add") {
904
- const newModel = queryInstructions.to;
905
- const { fields } = newModel;
906
- const columns = fields.map((field) => getFieldStatement(models, newModel, field)).filter(Boolean);
907
- dependencyStatements.push({
908
- statement: `${statement} (${columns.join(", ")})`,
909
- params: []
910
- });
911
- models.push(newModel);
912
- } else if (queryType === "set") {
913
- const newSlug = queryInstructions.to?.pluralSlug;
914
- if (newSlug) {
915
- const newTable = convertToSnakeCase(newSlug);
916
- dependencyStatements.push({
917
- statement: `${statement} RENAME TO "${newTable}"`,
918
- params: []
919
- });
920
- }
921
- Object.assign(targetModel, queryInstructions.to);
922
- } else if (queryType === "remove") {
923
- models.splice(models.indexOf(targetModel), 1);
924
- dependencyStatements.push({ statement, params: [] });
925
- }
926
- return;
927
809
  }
928
- if (queryModel === "field") {
929
- if (queryType === "add") {
930
- if (!instructionList.type) instructionList.type = "string";
931
- dependencyStatements.push({
932
- statement: `${statement} ADD COLUMN ${getFieldStatement(models, targetModel, instructionList)}`,
933
- params: []
934
- });
935
- } else if (queryType === "set") {
936
- const newSlug = queryInstructions.to?.slug;
937
- if (newSlug) {
938
- dependencyStatements.push({
939
- statement: `${statement} RENAME COLUMN "${slug}" TO "${newSlug}"`,
940
- params: []
941
- });
810
+ const pluralType = PLURAL_MODEL_ENTITIES[entity];
811
+ const jsonAction = action === "create" ? "insert" : action === "alter" ? "patch" : "remove";
812
+ let json = `json_${jsonAction}(${RONIN_MODEL_SYMBOLS.FIELD}${pluralType}, '$.${slug}'`;
813
+ if (jsonValue) json += `, ${prepareStatementValue(statementParams, jsonValue)}`;
814
+ json += ")";
815
+ return {
816
+ set: {
817
+ model: {
818
+ with: { slug: modelSlug },
819
+ to: {
820
+ [pluralType]: { [RONIN_MODEL_SYMBOLS.EXPRESSION]: json }
821
+ }
942
822
  }
943
- } else if (queryType === "remove") {
944
- dependencyStatements.push({
945
- statement: `${statement} DROP COLUMN "${slug}"`,
946
- params: []
947
- });
948
823
  }
949
- }
824
+ };
950
825
  };
951
826
 
952
827
  // src/instructions/before-after.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ronin/compiler",
3
- "version": "0.8.4",
3
+ "version": "0.8.6",
4
4
  "type": "module",
5
5
  "description": "Compiles RONIN queries to SQL statements.",
6
6
  "publishConfig": {