@promakeai/orm 1.0.6 → 1.3.1

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.js CHANGED
@@ -344,8 +344,13 @@ function getRefTargetFull(field) {
344
344
  }
345
345
  return { table: field.ref.table, field: field.ref.field || "id" };
346
346
  }
347
+ function getTablePermissions(table) {
348
+ return table.permissions;
349
+ }
347
350
 
348
351
  // src/schema/validator.ts
352
+ var VALID_ROLES = ["anon", "user", "admin"];
353
+ var VALID_ACTIONS = ["create", "read", "update", "delete"];
349
354
  var ValidationErrorCode = {
350
355
  MISSING_PRIMARY_KEY: "MISSING_PRIMARY_KEY",
351
356
  INVALID_REFERENCE: "INVALID_REFERENCE",
@@ -353,7 +358,9 @@ var ValidationErrorCode = {
353
358
  NO_LANGUAGES: "NO_LANGUAGES",
354
359
  DUPLICATE_TABLE: "DUPLICATE_TABLE",
355
360
  RESERVED_FIELD_NAME: "RESERVED_FIELD_NAME",
356
- SELF_REFERENCE_ON_REQUIRED: "SELF_REFERENCE_ON_REQUIRED"
361
+ SELF_REFERENCE_ON_REQUIRED: "SELF_REFERENCE_ON_REQUIRED",
362
+ INVALID_PERMISSION_ROLE: "INVALID_PERMISSION_ROLE",
363
+ INVALID_PERMISSION_ACTION: "INVALID_PERMISSION_ACTION"
357
364
  };
358
365
  var RESERVED_FIELDS = ["language_code"];
359
366
  function validateSchema(schema) {
@@ -412,6 +419,30 @@ function validateSchema(schema) {
412
419
  });
413
420
  }
414
421
  }
422
+ if (table.permissions) {
423
+ for (const [role, actions] of Object.entries(table.permissions)) {
424
+ if (!VALID_ROLES.includes(role)) {
425
+ errors.push({
426
+ table: tableName,
427
+ field: "$permissions",
428
+ message: `Invalid permission role: "${role}". Valid roles: ${VALID_ROLES.join(", ")}`,
429
+ code: ValidationErrorCode.INVALID_PERMISSION_ROLE
430
+ });
431
+ }
432
+ if (Array.isArray(actions)) {
433
+ for (const action of actions) {
434
+ if (!VALID_ACTIONS.includes(action)) {
435
+ errors.push({
436
+ table: tableName,
437
+ field: "$permissions",
438
+ message: `Invalid permission action: "${action}". Valid actions: ${VALID_ACTIONS.join(", ")}`,
439
+ code: ValidationErrorCode.INVALID_PERMISSION_ACTION
440
+ });
441
+ }
442
+ }
443
+ }
444
+ }
445
+ }
415
446
  }
416
447
  return errors;
417
448
  }
@@ -458,191 +489,6 @@ function validateTable(tableName, table, allTableNames) {
458
489
  }
459
490
  return errors;
460
491
  }
461
-
462
- // src/schema/fieldBuilder.ts
463
- class FieldBuilder {
464
- definition;
465
- constructor(type) {
466
- this.definition = {
467
- type,
468
- nullable: true,
469
- unique: false,
470
- primary: false,
471
- translatable: false
472
- };
473
- }
474
- required() {
475
- this.definition.nullable = false;
476
- return this;
477
- }
478
- nullable() {
479
- this.definition.nullable = true;
480
- return this;
481
- }
482
- unique() {
483
- this.definition.unique = true;
484
- return this;
485
- }
486
- default(value) {
487
- this.definition.default = value;
488
- return this;
489
- }
490
- translatable() {
491
- this.definition.translatable = true;
492
- return this;
493
- }
494
- ref(tableOrOptions) {
495
- this.definition.ref = tableOrOptions;
496
- return this;
497
- }
498
- trim() {
499
- this.definition.trim = true;
500
- return this;
501
- }
502
- lowercase() {
503
- this.definition.lowercase = true;
504
- return this;
505
- }
506
- uppercase() {
507
- this.definition.uppercase = true;
508
- return this;
509
- }
510
- minLength(value) {
511
- this.definition.minLength = value;
512
- return this;
513
- }
514
- maxLength(value) {
515
- this.definition.maxLength = value;
516
- return this;
517
- }
518
- min(value) {
519
- this.definition.min = value;
520
- return this;
521
- }
522
- max(value) {
523
- this.definition.max = value;
524
- return this;
525
- }
526
- enum(values) {
527
- this.definition.enum = values;
528
- return this;
529
- }
530
- match(pattern) {
531
- this.definition.match = pattern;
532
- return this;
533
- }
534
- build() {
535
- return { ...this.definition };
536
- }
537
- }
538
- var f = {
539
- id: () => {
540
- const builder = new FieldBuilder("id");
541
- builder["definition"].primary = true;
542
- builder["definition"].nullable = false;
543
- return builder;
544
- },
545
- string: () => new FieldBuilder("string"),
546
- text: () => new FieldBuilder("text"),
547
- int: () => new FieldBuilder("int"),
548
- decimal: () => new FieldBuilder("decimal"),
549
- bool: () => new FieldBuilder("bool"),
550
- timestamp: () => new FieldBuilder("timestamp"),
551
- json: () => new FieldBuilder("json"),
552
- stringArray: () => new FieldBuilder("string[]"),
553
- numberArray: () => new FieldBuilder("number[]"),
554
- boolArray: () => new FieldBuilder("boolean[]"),
555
- object: (properties) => {
556
- const builder = new FieldBuilder("object");
557
- builder["definition"].properties = properties;
558
- return builder;
559
- },
560
- objectArray: (properties) => {
561
- const builder = new FieldBuilder("object[]");
562
- builder["definition"].properties = properties;
563
- return builder;
564
- }
565
- };
566
-
567
- // src/schema/defineSchema.ts
568
- function defineSchema(input) {
569
- const languages = normalizeLanguages(input.languages);
570
- const tables = {};
571
- for (const [tableName, fields] of Object.entries(input.tables)) {
572
- tables[tableName] = {
573
- name: tableName,
574
- fields: Object.fromEntries(Object.entries(fields).map(([fieldName, builder]) => [
575
- fieldName,
576
- builder.build()
577
- ]))
578
- };
579
- }
580
- const schema = {
581
- name: input.name,
582
- languages,
583
- tables
584
- };
585
- assertValidSchema(schema);
586
- return schema;
587
- }
588
- function normalizeLanguages(input) {
589
- if (Array.isArray(input)) {
590
- if (input.length === 0) {
591
- throw new Error("At least one language must be defined");
592
- }
593
- return {
594
- default: input[0],
595
- supported: input
596
- };
597
- }
598
- return input;
599
- }
600
- function createSchemaUnsafe(input) {
601
- const languages = normalizeLanguages(input.languages);
602
- const tables = {};
603
- for (const [tableName, fields] of Object.entries(input.tables)) {
604
- tables[tableName] = {
605
- name: tableName,
606
- fields: Object.fromEntries(Object.entries(fields).map(([fieldName, builder]) => [
607
- fieldName,
608
- builder.build()
609
- ]))
610
- };
611
- }
612
- return {
613
- name: input.name,
614
- languages,
615
- tables
616
- };
617
- }
618
- function mergeSchemas(schemas) {
619
- if (schemas.length === 0) {
620
- throw new Error("At least one schema is required");
621
- }
622
- const defaultLang = schemas[0].languages.default;
623
- const allLangs = new Set;
624
- for (const schema of schemas) {
625
- for (const lang of schema.languages.supported) {
626
- allLangs.add(lang);
627
- }
628
- }
629
- const tables = {};
630
- for (const schema of schemas) {
631
- for (const [tableName, table] of Object.entries(schema.tables)) {
632
- if (tables[tableName]) {
633
- throw new Error(`Duplicate table name across schemas: ${tableName}`);
634
- }
635
- tables[tableName] = table;
636
- }
637
- }
638
- return {
639
- languages: {
640
- default: defaultLang,
641
- supported: Array.from(allLangs)
642
- },
643
- tables
644
- };
645
- }
646
492
  // src/schema/helpers.ts
647
493
  function singularize(word) {
648
494
  const irregulars = {
@@ -722,6 +568,338 @@ function toTranslationTableName(tableName) {
722
568
  function toTranslationFKName(tableName) {
723
569
  return `${singularize(tableName)}_id`;
724
570
  }
571
+ // src/adapters/RestAdapter.ts
572
+ class RestAdapter {
573
+ baseUrl;
574
+ databasePrefix;
575
+ token;
576
+ getTokenFn;
577
+ customHeaders;
578
+ fetchFn;
579
+ timeout;
580
+ schema;
581
+ defaultLang;
582
+ constructor(config) {
583
+ this.baseUrl = config.baseUrl.replace(/\/+$/, "");
584
+ this.databasePrefix = config.databasePrefix ?? "/database";
585
+ this.token = config.token;
586
+ this.getTokenFn = config.getToken;
587
+ this.customHeaders = config.headers ?? {};
588
+ const gf = globalThis;
589
+ this.fetchFn = config.fetch ?? gf.fetch.bind(gf);
590
+ this.timeout = config.timeout ?? 30000;
591
+ this.schema = config.schema;
592
+ this.defaultLang = config.defaultLang;
593
+ }
594
+ buildUrl(path) {
595
+ return `${this.baseUrl}${this.databasePrefix}${path}`;
596
+ }
597
+ getHeaders() {
598
+ const headers = {
599
+ "Content-Type": "application/json",
600
+ Accept: "application/json",
601
+ ...this.customHeaders
602
+ };
603
+ const token = this.getTokenFn ? this.getTokenFn() : this.token;
604
+ if (token) {
605
+ headers["Authorization"] = `Bearer ${token}`;
606
+ }
607
+ return headers;
608
+ }
609
+ async request(url, init) {
610
+ const controller = new AbortController;
611
+ const timer = setTimeout(() => controller.abort(), this.timeout);
612
+ try {
613
+ const response = await this.fetchFn(url, {
614
+ ...init,
615
+ headers: { ...this.getHeaders(), ...init?.headers ?? {} },
616
+ signal: controller.signal
617
+ });
618
+ if (!response.ok) {
619
+ const body = await response.json().catch(() => null);
620
+ const message = body?.message || body?.error || `HTTP ${response.status} ${response.statusText}`;
621
+ throw new Error(message);
622
+ }
623
+ return await response.json();
624
+ } finally {
625
+ clearTimeout(timer);
626
+ }
627
+ }
628
+ buildQueryParams(options) {
629
+ const params = new URLSearchParams;
630
+ if (!options)
631
+ return params;
632
+ if (options.where && Object.keys(options.where).length > 0) {
633
+ params.set("where", JSON.stringify(options.where));
634
+ }
635
+ if (options.orderBy?.length) {
636
+ params.set("order", options.orderBy.map((o) => `${o.field}:${o.direction}`).join(","));
637
+ }
638
+ if (options.limit != null) {
639
+ params.set("limit", String(options.limit));
640
+ }
641
+ if (options.offset != null) {
642
+ params.set("offset", String(options.offset));
643
+ }
644
+ if (options.lang) {
645
+ params.set("lang", options.lang);
646
+ }
647
+ if (options.fallbackLang) {
648
+ params.set("fallback_lang", options.fallbackLang);
649
+ }
650
+ return params;
651
+ }
652
+ urlWithParams(base, params) {
653
+ const qs = params.toString();
654
+ return qs ? `${base}?${qs}` : base;
655
+ }
656
+ setSchema(schema) {
657
+ this.schema = schema;
658
+ }
659
+ async connect() {
660
+ if (!this.schema)
661
+ return;
662
+ const apiSchema = {};
663
+ for (const [tableName, tableDef] of Object.entries(this.schema.tables)) {
664
+ const columns = [];
665
+ for (const [fieldName, fieldDef] of Object.entries(tableDef.fields)) {
666
+ const col = {
667
+ name: fieldName,
668
+ type: this.mapFieldType(fieldDef.type)
669
+ };
670
+ if (fieldDef.primary)
671
+ col.primary_key = true;
672
+ if (!fieldDef.nullable)
673
+ col.not_null = true;
674
+ if (fieldDef.unique)
675
+ col.unique = true;
676
+ if (fieldDef.default !== undefined)
677
+ col.default_value = String(fieldDef.default);
678
+ if (fieldDef.translatable)
679
+ col.translatable = true;
680
+ columns.push(col);
681
+ }
682
+ const tableEntry = { columns };
683
+ if (tableDef.permissions) {
684
+ tableEntry.permissions = tableDef.permissions;
685
+ }
686
+ apiSchema[tableName] = tableEntry;
687
+ }
688
+ await this.request(this.buildUrl("/generate"), {
689
+ method: "POST",
690
+ body: JSON.stringify({ schema: { tables: apiSchema } })
691
+ });
692
+ }
693
+ mapFieldType(type) {
694
+ switch (type) {
695
+ case "id":
696
+ case "int":
697
+ return "INTEGER";
698
+ case "string":
699
+ case "text":
700
+ case "timestamp":
701
+ return "TEXT";
702
+ case "decimal":
703
+ return "REAL";
704
+ case "bool":
705
+ return "INTEGER";
706
+ case "json":
707
+ case "object":
708
+ case "object[]":
709
+ case "string[]":
710
+ case "number[]":
711
+ case "boolean[]":
712
+ return "TEXT";
713
+ default:
714
+ return "TEXT";
715
+ }
716
+ }
717
+ close() {}
718
+ async list(table, options) {
719
+ const params = this.buildQueryParams(options);
720
+ const url = this.urlWithParams(this.buildUrl(`/${table}/list`), params);
721
+ const res = await this.request(url);
722
+ return res.data;
723
+ }
724
+ async get(table, id, options) {
725
+ const params = new URLSearchParams;
726
+ if (options?.lang)
727
+ params.set("lang", options.lang);
728
+ if (options?.fallbackLang)
729
+ params.set("fallback_lang", options.fallbackLang);
730
+ const url = this.urlWithParams(this.buildUrl(`/${table}/${id}`), params);
731
+ try {
732
+ const res = await this.request(url);
733
+ return res.data ?? null;
734
+ } catch (err) {
735
+ if (err instanceof Error && err.message.includes("404")) {
736
+ return null;
737
+ }
738
+ throw err;
739
+ }
740
+ }
741
+ async findOne(table, options) {
742
+ const results = await this.list(table, { ...options, limit: 1 });
743
+ return results[0] ?? null;
744
+ }
745
+ async count(table, options) {
746
+ const params = new URLSearchParams;
747
+ if (options?.where && Object.keys(options.where).length > 0) {
748
+ params.set("where", JSON.stringify(options.where));
749
+ }
750
+ const url = this.urlWithParams(this.buildUrl(`/${table}/count`), params);
751
+ const res = await this.request(url);
752
+ return res.count;
753
+ }
754
+ async paginate(table, page, limit, options) {
755
+ const offset = (page - 1) * limit;
756
+ const [total, data] = await Promise.all([
757
+ this.count(table, options),
758
+ this.list(table, { ...options, limit, offset })
759
+ ]);
760
+ const totalPages = Math.ceil(total / limit);
761
+ return {
762
+ data,
763
+ page,
764
+ limit,
765
+ total,
766
+ totalPages,
767
+ hasMore: page < totalPages
768
+ };
769
+ }
770
+ async create(table, data) {
771
+ const url = this.buildUrl(`/${table}/create`);
772
+ const res = await this.request(url, {
773
+ method: "POST",
774
+ body: JSON.stringify({ data })
775
+ });
776
+ const result = res.data ?? {};
777
+ if (res.id !== undefined && !("id" in result)) {
778
+ result.id = res.id;
779
+ }
780
+ return result;
781
+ }
782
+ async update(table, id, data, options) {
783
+ const url = this.buildUrl(`/${table}/${id}`);
784
+ const body = { data };
785
+ if (options?.translations) {
786
+ body.translations = options.translations;
787
+ }
788
+ const res = await this.request(url, {
789
+ method: "PUT",
790
+ body: JSON.stringify(body)
791
+ });
792
+ return res.data;
793
+ }
794
+ async delete(table, id) {
795
+ const url = this.buildUrl(`/${table}/${id}`);
796
+ try {
797
+ const res = await this.request(url, {
798
+ method: "DELETE"
799
+ });
800
+ return res.deleted ?? true;
801
+ } catch (err) {
802
+ if (err instanceof Error && err.message.includes("404")) {
803
+ return false;
804
+ }
805
+ throw err;
806
+ }
807
+ }
808
+ async createMany(table, records, options) {
809
+ const url = this.buildUrl(`/${table}/create-batch`);
810
+ const res = await this.request(url, {
811
+ method: "POST",
812
+ body: JSON.stringify({
813
+ records,
814
+ ignore: options?.ignore ?? false,
815
+ no_atomic: options?.noAtomic ?? false
816
+ })
817
+ });
818
+ return { created: res.created, ids: res.ids };
819
+ }
820
+ async updateMany(table, updates, options) {
821
+ const url = this.buildUrl(`/${table}/update-batch`);
822
+ const res = await this.request(url, {
823
+ method: "POST",
824
+ body: JSON.stringify({
825
+ updates,
826
+ no_atomic: options?.noAtomic ?? false
827
+ })
828
+ });
829
+ return { updated: res.updated };
830
+ }
831
+ async deleteMany(table, ids, options) {
832
+ const url = this.buildUrl(`/${table}/delete-batch`);
833
+ const res = await this.request(url, {
834
+ method: "POST",
835
+ body: JSON.stringify({
836
+ ids,
837
+ no_atomic: options?.noAtomic ?? false
838
+ })
839
+ });
840
+ return { deleted: res.deleted };
841
+ }
842
+ async createWithTranslations(table, data, translations) {
843
+ const url = this.buildUrl(`/${table}/create`);
844
+ const res = await this.request(url, {
845
+ method: "POST",
846
+ body: JSON.stringify({ data, translations })
847
+ });
848
+ const result = res.data ?? {};
849
+ if (res.id !== undefined && !("id" in result)) {
850
+ result.id = res.id;
851
+ }
852
+ return result;
853
+ }
854
+ async upsertTranslation(table, id, lang, data) {
855
+ const url = this.buildUrl(`/${table}/${id}`);
856
+ await this.request(url, {
857
+ method: "PUT",
858
+ body: JSON.stringify({ data, lang })
859
+ });
860
+ }
861
+ async getTranslations(table, id) {
862
+ const translationTable = toTranslationTableName(table);
863
+ const fkName = toTranslationFKName(table);
864
+ const params = new URLSearchParams;
865
+ params.set("where", JSON.stringify({ [fkName]: id }));
866
+ const url = this.urlWithParams(this.buildUrl(`/${translationTable}/list`), params);
867
+ const res = await this.request(url);
868
+ return res.data;
869
+ }
870
+ async raw(query, params) {
871
+ const url = this.buildUrl("/exec");
872
+ const res = await this.request(url, {
873
+ method: "POST",
874
+ body: JSON.stringify({ sql: query, params: params ?? [] })
875
+ });
876
+ return res.data;
877
+ }
878
+ async execute(query, params) {
879
+ const url = this.buildUrl("/exec");
880
+ const res = await this.request(url, {
881
+ method: "POST",
882
+ body: JSON.stringify({ sql: query, params: params ?? [] })
883
+ });
884
+ return {
885
+ changes: res.changes,
886
+ lastInsertRowid: res.last_insert_rowid ?? 0
887
+ };
888
+ }
889
+ async beginTransaction() {}
890
+ async commit() {}
891
+ async rollback() {}
892
+ async getTables() {
893
+ const url = this.buildUrl("/tables");
894
+ const res = await this.request(url);
895
+ return res.tables;
896
+ }
897
+ async getTableSchema(table) {
898
+ const url = this.buildUrl(`/${table}/schema`);
899
+ const res = await this.request(url);
900
+ return res.columns;
901
+ }
902
+ }
725
903
  // src/utils/whereBuilder.ts
726
904
  var COMPARISON_OPERATORS = {
727
905
  $eq: "=",
@@ -1031,12 +1209,18 @@ function parseJSONSchemaWithWarnings(json) {
1031
1209
  const tables = {};
1032
1210
  for (const [tableName, jsonTable] of Object.entries(json.tables)) {
1033
1211
  const fields = {};
1212
+ let permissions;
1034
1213
  for (const [fieldName, jsonField] of Object.entries(jsonTable)) {
1214
+ if (fieldName === "$permissions") {
1215
+ permissions = jsonField;
1216
+ continue;
1217
+ }
1035
1218
  fields[fieldName] = convertJSONField(jsonField);
1036
1219
  }
1037
1220
  tables[tableName] = {
1038
1221
  name: tableName,
1039
- fields
1222
+ fields,
1223
+ ...permissions ? { permissions } : {}
1040
1224
  };
1041
1225
  }
1042
1226
  return {
@@ -1128,7 +1312,7 @@ function convertJSONField(jsonField) {
1128
1312
  type,
1129
1313
  nullable: jsonField.nullable ?? !jsonField.required,
1130
1314
  unique: jsonField.unique ?? false,
1131
- primary: jsonField.primary ?? false,
1315
+ primary: jsonField.primary ?? type === "id",
1132
1316
  default: jsonField.default,
1133
1317
  translatable: jsonField.translatable ?? false,
1134
1318
  properties,
@@ -1198,13 +1382,13 @@ export {
1198
1382
  pluralize,
1199
1383
  parseJSONSchemaWithWarnings,
1200
1384
  parseJSONSchema,
1201
- mergeSchemas,
1202
1385
  isValidSchema,
1203
1386
  isRequiredField,
1204
1387
  isJsonType,
1205
1388
  hasTranslatableFields,
1206
1389
  getTranslationTableFields,
1207
1390
  getTranslatableFields,
1391
+ getTablePermissions,
1208
1392
  getRequiredFields,
1209
1393
  getReferenceFields,
1210
1394
  getRefTargetFull,
@@ -1214,11 +1398,8 @@ export {
1214
1398
  getNonTranslatableFields,
1215
1399
  getMainTableFields,
1216
1400
  getInsertableFields,
1217
- f,
1218
1401
  extractTranslatableData,
1219
1402
  deserializeRow,
1220
- defineSchema,
1221
- createSchemaUnsafe,
1222
1403
  buildWhereClause,
1223
1404
  buildTranslationUpsert,
1224
1405
  buildTranslationQueryById,
@@ -1226,5 +1407,6 @@ export {
1226
1407
  buildTranslationInsert,
1227
1408
  assertValidSchema,
1228
1409
  ValidationErrorCode,
1410
+ RestAdapter,
1229
1411
  ORM
1230
1412
  };
@@ -1,9 +1,7 @@
1
1
  /**
2
2
  * Schema Module Exports
3
3
  */
4
- export { defineSchema, f, mergeSchemas, createSchemaUnsafe } from "./defineSchema";
5
- export type { FieldBuilder } from "./fieldBuilder";
6
4
  export { validateSchema, assertValidSchema, isValidSchema, validateTable, ValidationErrorCode, } from "./validator";
7
5
  export type { ValidationError } from "./validator";
8
6
  export { singularize, pluralize, toPascalCase, toCamelCase, toSnakeCase, toInterfaceName, toDbInterfaceName, toPascalCasePlural, toTranslationTableName, toTranslationFKName, } from "./helpers";
9
- export { getTranslatableFields, getNonTranslatableFields, getInsertableFields, hasTranslatableFields, getPrimaryKeyField, getReferenceFields, getMainTableFields, getTranslationTableFields, isRequiredField, getRequiredFields, getRefTarget, getRefTargetFull, } from "./schemaHelpers";
7
+ export { getTranslatableFields, getNonTranslatableFields, getInsertableFields, hasTranslatableFields, getPrimaryKeyField, getReferenceFields, getMainTableFields, getTranslationTableFields, isRequiredField, getRequiredFields, getRefTarget, getRefTargetFull, getTablePermissions, } from "./schemaHelpers";
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Utilities for working with schema definitions.
5
5
  */
6
- import type { TableDefinition, FieldDefinition, FieldReference } from "../types";
6
+ import type { TableDefinition, FieldDefinition, FieldReference, TablePermissions } from "../types";
7
7
  /**
8
8
  * Get names of translatable fields in a table
9
9
  */
@@ -53,3 +53,7 @@ export declare function getRefTarget(field: FieldDefinition): string | null;
53
53
  * Returns { table, field } object
54
54
  */
55
55
  export declare function getRefTargetFull(field: FieldDefinition): FieldReference | null;
56
+ /**
57
+ * Get table permissions (undefined if no restrictions)
58
+ */
59
+ export declare function getTablePermissions(table: TableDefinition): TablePermissions | undefined;
@@ -24,6 +24,8 @@ export declare const ValidationErrorCode: {
24
24
  readonly DUPLICATE_TABLE: "DUPLICATE_TABLE";
25
25
  readonly RESERVED_FIELD_NAME: "RESERVED_FIELD_NAME";
26
26
  readonly SELF_REFERENCE_ON_REQUIRED: "SELF_REFERENCE_ON_REQUIRED";
27
+ readonly INVALID_PERMISSION_ROLE: "INVALID_PERMISSION_ROLE";
28
+ readonly INVALID_PERMISSION_ACTION: "INVALID_PERMISSION_ACTION";
27
29
  };
28
30
  /**
29
31
  * Validate a schema definition