arkormx 1.1.0 → 1.2.0
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/cli.mjs +281 -7
- package/dist/index.cjs +288 -7
- package/dist/index.d.cts +108 -2
- package/dist/index.d.mts +108 -2
- package/dist/index.mjs +282 -8
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -129,6 +129,95 @@ var ForeignKeyBuilder = class {
|
|
|
129
129
|
|
|
130
130
|
//#endregion
|
|
131
131
|
//#region src/database/TableBuilder.ts
|
|
132
|
+
const PRISMA_ENUM_MEMBER_REGEX$1 = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
133
|
+
const normalizeEnumMember = (columnName, value) => {
|
|
134
|
+
const normalized = value.trim();
|
|
135
|
+
if (!normalized) throw new Error(`Enum column [${columnName}] must define only non-empty values.`);
|
|
136
|
+
if (!PRISMA_ENUM_MEMBER_REGEX$1.test(normalized)) throw new Error(`Enum column [${columnName}] contains invalid Prisma enum value [${normalized}].`);
|
|
137
|
+
return normalized;
|
|
138
|
+
};
|
|
139
|
+
const normalizeEnumMembers = (columnName, values) => {
|
|
140
|
+
const normalizedValues = values.map((value) => normalizeEnumMember(columnName, value));
|
|
141
|
+
const seen = /* @__PURE__ */ new Set();
|
|
142
|
+
for (const value of normalizedValues) {
|
|
143
|
+
if (seen.has(value)) throw new Error(`Enum column [${columnName}] contains duplicate enum value [${value}].`);
|
|
144
|
+
seen.add(value);
|
|
145
|
+
}
|
|
146
|
+
return normalizedValues;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* The EnumBuilder class provides a fluent interface for configuring enum columns
|
|
150
|
+
* after they are defined on a table.
|
|
151
|
+
*
|
|
152
|
+
* @author Legacy (3m1n3nc3)
|
|
153
|
+
* @since 0.2.3
|
|
154
|
+
*/
|
|
155
|
+
var EnumBuilder = class {
|
|
156
|
+
tableBuilder;
|
|
157
|
+
columnName;
|
|
158
|
+
constructor(tableBuilder, columnName) {
|
|
159
|
+
this.tableBuilder = tableBuilder;
|
|
160
|
+
this.columnName = columnName;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Defines the Prisma enum name for this column.
|
|
164
|
+
*
|
|
165
|
+
* @param name
|
|
166
|
+
* @returns
|
|
167
|
+
*/
|
|
168
|
+
enumName(name) {
|
|
169
|
+
this.tableBuilder.enumName(name, this.columnName);
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Marks the enum column as nullable.
|
|
174
|
+
*
|
|
175
|
+
* @returns
|
|
176
|
+
*/
|
|
177
|
+
nullable() {
|
|
178
|
+
this.tableBuilder.nullable(this.columnName);
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Marks the enum column as unique.
|
|
183
|
+
*
|
|
184
|
+
* @returns
|
|
185
|
+
*/
|
|
186
|
+
unique() {
|
|
187
|
+
this.tableBuilder.unique(this.columnName);
|
|
188
|
+
return this;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Sets a default value for the enum column.
|
|
192
|
+
*
|
|
193
|
+
* @param value
|
|
194
|
+
* @returns
|
|
195
|
+
*/
|
|
196
|
+
default(value) {
|
|
197
|
+
this.tableBuilder.default(value, this.columnName);
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Positions the enum column after another column when supported.
|
|
202
|
+
*
|
|
203
|
+
* @param referenceColumn
|
|
204
|
+
* @returns
|
|
205
|
+
*/
|
|
206
|
+
after(referenceColumn) {
|
|
207
|
+
this.tableBuilder.after(referenceColumn, this.columnName);
|
|
208
|
+
return this;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Maps the enum column to a custom database column name.
|
|
212
|
+
*
|
|
213
|
+
* @param name
|
|
214
|
+
* @returns
|
|
215
|
+
*/
|
|
216
|
+
map(name) {
|
|
217
|
+
this.tableBuilder.map(name, this.columnName);
|
|
218
|
+
return this;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
132
221
|
/**
|
|
133
222
|
* The TableBuilder class provides a fluent interface for defining
|
|
134
223
|
* the structure of a database table in a migration, including columns to add or drop.
|
|
@@ -181,6 +270,27 @@ var TableBuilder = class {
|
|
|
181
270
|
return this.column(name, "uuid", options);
|
|
182
271
|
}
|
|
183
272
|
/**
|
|
273
|
+
* Defines an enum column in the table.
|
|
274
|
+
*
|
|
275
|
+
* @param name The name of the enum column.
|
|
276
|
+
* @param values Either an array of string values for the enum or the name of an existing enum to reuse.
|
|
277
|
+
* @param options Additional options for the enum column.
|
|
278
|
+
* @returns
|
|
279
|
+
*/
|
|
280
|
+
enum(name, valuesOrEnumName, options = {}) {
|
|
281
|
+
const isEnumReuse = typeof valuesOrEnumName === "string";
|
|
282
|
+
if (!isEnumReuse && valuesOrEnumName.length === 0) throw new Error(`Enum column [${name}] must define at least one value.`);
|
|
283
|
+
const normalizedEnumValues = isEnumReuse ? void 0 : normalizeEnumMembers(name, valuesOrEnumName);
|
|
284
|
+
const enumName = isEnumReuse ? valuesOrEnumName.trim() : options.enumName?.trim();
|
|
285
|
+
if (isEnumReuse && !enumName) throw new Error(`Enum column [${name}] must define an enum name.`);
|
|
286
|
+
this.column(name, "enum", {
|
|
287
|
+
...options,
|
|
288
|
+
enumName,
|
|
289
|
+
enumValues: normalizedEnumValues
|
|
290
|
+
});
|
|
291
|
+
return new EnumBuilder(this, name);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
184
294
|
* Defines a string column in the table.
|
|
185
295
|
*
|
|
186
296
|
* @param name The name of the string column.
|
|
@@ -350,6 +460,21 @@ var TableBuilder = class {
|
|
|
350
460
|
return this;
|
|
351
461
|
}
|
|
352
462
|
/**
|
|
463
|
+
* Sets the Prisma enum name for an enum column.
|
|
464
|
+
*
|
|
465
|
+
* @param name The enum name to assign.
|
|
466
|
+
* @param columnName Optional explicit target column name. When omitted, applies to the latest defined column.
|
|
467
|
+
* @returns The current TableBuilder instance for chaining.
|
|
468
|
+
*/
|
|
469
|
+
enumName(name, columnName) {
|
|
470
|
+
const column = this.resolveColumn(columnName);
|
|
471
|
+
if (column.type !== "enum") throw new Error(`Column [${column.name}] is not an enum column.`);
|
|
472
|
+
const enumName = name.trim();
|
|
473
|
+
if (!enumName) throw new Error(`Enum column [${column.name}] must define an enum name.`);
|
|
474
|
+
column.enumName = enumName;
|
|
475
|
+
return this;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
353
478
|
* Sets a default value for a column.
|
|
354
479
|
*
|
|
355
480
|
* @param value The default scalar value or Prisma expression (e.g. 'now()').
|
|
@@ -432,7 +557,10 @@ var TableBuilder = class {
|
|
|
432
557
|
* @returns
|
|
433
558
|
*/
|
|
434
559
|
getColumns() {
|
|
435
|
-
return this.columns.map((column) => ({
|
|
560
|
+
return this.columns.map((column) => ({
|
|
561
|
+
...column,
|
|
562
|
+
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
563
|
+
}));
|
|
436
564
|
}
|
|
437
565
|
/**
|
|
438
566
|
* Returns a copy of the defined column names to be dropped from the table.
|
|
@@ -473,6 +601,8 @@ var TableBuilder = class {
|
|
|
473
601
|
this.columns.push({
|
|
474
602
|
name,
|
|
475
603
|
type,
|
|
604
|
+
enumName: options.enumName,
|
|
605
|
+
enumValues: options.enumValues ? [...options.enumValues] : void 0,
|
|
476
606
|
map: options.map,
|
|
477
607
|
nullable: options.nullable,
|
|
478
608
|
unique: options.unique,
|
|
@@ -572,7 +702,10 @@ var SchemaBuilder = class {
|
|
|
572
702
|
return this.operations.map((operation) => {
|
|
573
703
|
if (operation.type === "createTable") return {
|
|
574
704
|
...operation,
|
|
575
|
-
columns: operation.columns.map((column) => ({
|
|
705
|
+
columns: operation.columns.map((column) => ({
|
|
706
|
+
...column,
|
|
707
|
+
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
708
|
+
})),
|
|
576
709
|
indexes: operation.indexes.map((index) => ({
|
|
577
710
|
...index,
|
|
578
711
|
columns: [...index.columns]
|
|
@@ -581,7 +714,10 @@ var SchemaBuilder = class {
|
|
|
581
714
|
};
|
|
582
715
|
if (operation.type === "alterTable") return {
|
|
583
716
|
...operation,
|
|
584
|
-
addColumns: operation.addColumns.map((column) => ({
|
|
717
|
+
addColumns: operation.addColumns.map((column) => ({
|
|
718
|
+
...column,
|
|
719
|
+
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
720
|
+
})),
|
|
585
721
|
dropColumns: [...operation.dropColumns],
|
|
586
722
|
addIndexes: operation.addIndexes.map((index) => ({
|
|
587
723
|
...index,
|
|
@@ -597,6 +733,8 @@ var SchemaBuilder = class {
|
|
|
597
733
|
//#endregion
|
|
598
734
|
//#region src/helpers/migrations.ts
|
|
599
735
|
const PRISMA_MODEL_REGEX = /model\s+(\w+)\s*\{[\s\S]*?\n\}/g;
|
|
736
|
+
const PRISMA_ENUM_REGEX = /enum\s+(\w+)\s*\{[\s\S]*?\n\}/g;
|
|
737
|
+
const PRISMA_ENUM_MEMBER_REGEX = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
600
738
|
/**
|
|
601
739
|
* Convert a table name to a PascalCase model name, with basic singularization.
|
|
602
740
|
*
|
|
@@ -624,6 +762,7 @@ const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
|
624
762
|
*/
|
|
625
763
|
const resolvePrismaType = (column) => {
|
|
626
764
|
if (column.type === "id") return "Int";
|
|
765
|
+
if (column.type === "enum") return resolveEnumName(column);
|
|
627
766
|
if (column.type === "uuid") return "String";
|
|
628
767
|
if (column.type === "string" || column.type === "text") return "String";
|
|
629
768
|
if (column.type === "integer") return "Int";
|
|
@@ -633,6 +772,11 @@ const resolvePrismaType = (column) => {
|
|
|
633
772
|
if (column.type === "json") return "Json";
|
|
634
773
|
return "DateTime";
|
|
635
774
|
};
|
|
775
|
+
const resolveEnumName = (column) => {
|
|
776
|
+
if (column.type !== "enum") throw new ArkormException(`Column [${column.name}] is not an enum column.`);
|
|
777
|
+
if (column.enumName && column.enumName.trim().length > 0) return column.enumName.trim();
|
|
778
|
+
throw new ArkormException(`Enum column [${column.name}] must define an enum name.`);
|
|
779
|
+
};
|
|
636
780
|
/**
|
|
637
781
|
* Format a default value for inclusion in a Prisma schema field definition, based on its type.
|
|
638
782
|
*
|
|
@@ -647,6 +791,61 @@ const formatDefaultValue = (value) => {
|
|
|
647
791
|
if (typeof value === "boolean") return `@default(${value ? "true" : "false"})`;
|
|
648
792
|
};
|
|
649
793
|
/**
|
|
794
|
+
* Format a default value for an enum column as a Prisma @default attribute, validating that it is a non-empty string.
|
|
795
|
+
*
|
|
796
|
+
* @param value
|
|
797
|
+
* @returns
|
|
798
|
+
*/
|
|
799
|
+
const formatEnumDefaultValue = (value) => {
|
|
800
|
+
if (value == null) return void 0;
|
|
801
|
+
if (typeof value !== "string" || value.trim().length === 0) throw new ArkormException("Enum default values must be provided as non-empty strings.");
|
|
802
|
+
return `@default(${value.trim()})`;
|
|
803
|
+
};
|
|
804
|
+
/**
|
|
805
|
+
* Normalize an enum value by ensuring it is a non-empty string and trimming whitespace.
|
|
806
|
+
*
|
|
807
|
+
* @param value
|
|
808
|
+
* @returns
|
|
809
|
+
*/
|
|
810
|
+
const normalizeEnumValue = (value) => {
|
|
811
|
+
if (typeof value !== "string" || value.trim().length === 0) throw new ArkormException("Enum values must be provided as non-empty strings.");
|
|
812
|
+
const normalized = value.trim();
|
|
813
|
+
if (!PRISMA_ENUM_MEMBER_REGEX.test(normalized)) throw new ArkormException(`Enum value [${normalized}] is not a valid Prisma enum member name.`);
|
|
814
|
+
return normalized;
|
|
815
|
+
};
|
|
816
|
+
/**
|
|
817
|
+
* Extract the enum values from a Prisma enum block string.
|
|
818
|
+
*
|
|
819
|
+
* @param block
|
|
820
|
+
* @returns
|
|
821
|
+
*/
|
|
822
|
+
const extractEnumBlockValues = (block) => {
|
|
823
|
+
return block.split("\n").slice(1, -1).map((line) => line.trim()).filter(Boolean);
|
|
824
|
+
};
|
|
825
|
+
const validateEnumValues = (column, enumName, enumValues) => {
|
|
826
|
+
const normalizedValues = enumValues.map(normalizeEnumValue);
|
|
827
|
+
const seen = /* @__PURE__ */ new Set();
|
|
828
|
+
for (const value of normalizedValues) {
|
|
829
|
+
if (seen.has(value)) throw new ArkormException(`Prisma enum [${enumName}] for column [${column.name}] contains duplicate value [${value}].`);
|
|
830
|
+
seen.add(value);
|
|
831
|
+
}
|
|
832
|
+
return normalizedValues;
|
|
833
|
+
};
|
|
834
|
+
/**
|
|
835
|
+
* Validate that a default value for an enum column is included in the defined enum values.
|
|
836
|
+
*
|
|
837
|
+
* @param column
|
|
838
|
+
* @param enumName
|
|
839
|
+
* @param enumValues
|
|
840
|
+
* @returns
|
|
841
|
+
*/
|
|
842
|
+
const validateEnumDefaultValue = (column, enumName, enumValues) => {
|
|
843
|
+
if (column.default == null) return;
|
|
844
|
+
const normalizedDefault = normalizeEnumValue(column.default);
|
|
845
|
+
if (enumValues.includes(normalizedDefault)) return;
|
|
846
|
+
throw new ArkormException(`Enum default value [${normalizedDefault}] is not defined in Prisma enum [${enumName}] for column [${column.name}].`);
|
|
847
|
+
};
|
|
848
|
+
/**
|
|
650
849
|
* Build a single line of a Prisma model field definition based on a SchemaColumn, including type and modifiers.
|
|
651
850
|
*
|
|
652
851
|
* @param column
|
|
@@ -667,11 +866,82 @@ const buildFieldLine = (column) => {
|
|
|
667
866
|
const primary = column.primary ? " @id" : "";
|
|
668
867
|
const mapped = typeof column.map === "string" && column.map.trim().length > 0 ? ` @map("${column.map.replace(/"/g, "\\\"")}")` : "";
|
|
669
868
|
const updatedAt = column.updatedAt ? " @updatedAt" : "";
|
|
670
|
-
const defaultValue = formatDefaultValue(column.default) ?? (column.type === "uuid" && column.primary ? "@default(uuid())" : void 0);
|
|
869
|
+
const defaultValue = column.type === "enum" ? formatEnumDefaultValue(column.default) : formatDefaultValue(column.default) ?? (column.type === "uuid" && column.primary ? "@default(uuid())" : void 0);
|
|
671
870
|
const defaultSuffix = defaultValue ? ` ${defaultValue}` : "";
|
|
672
871
|
return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${updatedAt}${mapped}`;
|
|
673
872
|
};
|
|
674
873
|
/**
|
|
874
|
+
* Build a Prisma enum block string based on an enum name and its values, validating that
|
|
875
|
+
* at least one value is provided.
|
|
876
|
+
*
|
|
877
|
+
* @param enumName The name of the enum to create.
|
|
878
|
+
* @param values The array of values for the enum.
|
|
879
|
+
* @returns The Prisma enum block string.
|
|
880
|
+
*/
|
|
881
|
+
const buildEnumBlock = (enumName, values) => {
|
|
882
|
+
if (values.length === 0) throw new ArkormException(`Enum [${enumName}] must define at least one value.`);
|
|
883
|
+
return `enum ${enumName} {\n${values.map((value) => ` ${value}`).join("\n")}\n}`;
|
|
884
|
+
};
|
|
885
|
+
/**
|
|
886
|
+
* Find the Prisma enum block in a schema string that corresponds to a given enum
|
|
887
|
+
* name, returning its details if found.
|
|
888
|
+
*
|
|
889
|
+
* @param schema The Prisma schema string to search for the enum block.
|
|
890
|
+
* @param enumName The name of the enum to find in the schema.
|
|
891
|
+
* @returns
|
|
892
|
+
*/
|
|
893
|
+
const findEnumBlock = (schema, enumName) => {
|
|
894
|
+
const candidates = [...schema.matchAll(PRISMA_ENUM_REGEX)];
|
|
895
|
+
for (const match of candidates) {
|
|
896
|
+
const block = match[0];
|
|
897
|
+
const matchedEnumName = match[1];
|
|
898
|
+
const start = match.index ?? 0;
|
|
899
|
+
const end = start + block.length;
|
|
900
|
+
if (matchedEnumName === enumName) return {
|
|
901
|
+
enumName: matchedEnumName,
|
|
902
|
+
block,
|
|
903
|
+
start,
|
|
904
|
+
end
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
return null;
|
|
908
|
+
};
|
|
909
|
+
/**
|
|
910
|
+
* Ensure that Prisma enum blocks exist in the schema for any enum columns defined in a
|
|
911
|
+
* create or alter table operation, adding them if necessary and validating against
|
|
912
|
+
* existing blocks.
|
|
913
|
+
*
|
|
914
|
+
* @param schema The current Prisma schema string to check and modify.
|
|
915
|
+
* @param columns The array of schema column definitions to check for enum types and ensure corresponding blocks exist for.
|
|
916
|
+
* @returns
|
|
917
|
+
*/
|
|
918
|
+
const ensureEnumBlocks = (schema, columns) => {
|
|
919
|
+
let nextSchema = schema;
|
|
920
|
+
for (const column of columns) {
|
|
921
|
+
if (column.type !== "enum") continue;
|
|
922
|
+
const enumName = resolveEnumName(column);
|
|
923
|
+
const enumValues = column.enumValues ?? [];
|
|
924
|
+
const existing = findEnumBlock(nextSchema, enumName);
|
|
925
|
+
if (existing) {
|
|
926
|
+
const existingValues = validateEnumValues(column, enumName, extractEnumBlockValues(existing.block));
|
|
927
|
+
if (enumValues.length === 0) {
|
|
928
|
+
validateEnumDefaultValue(column, enumName, existingValues);
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
const normalizedEnumValues = validateEnumValues(column, enumName, enumValues);
|
|
932
|
+
if (existingValues.join("|") !== normalizedEnumValues.join("|")) throw new ArkormException(`Prisma enum [${enumName}] already exists with different values.`);
|
|
933
|
+
validateEnumDefaultValue(column, enumName, existingValues);
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
if (enumValues.length === 0) throw new ArkormException(`Prisma enum [${enumName}] was not found for column [${column.name}].`);
|
|
937
|
+
const normalizedEnumValues = validateEnumValues(column, enumName, enumValues);
|
|
938
|
+
validateEnumDefaultValue(column, enumName, normalizedEnumValues);
|
|
939
|
+
const block = buildEnumBlock(enumName, normalizedEnumValues);
|
|
940
|
+
nextSchema = `${nextSchema.trimEnd()}\n\n${block}\n`;
|
|
941
|
+
}
|
|
942
|
+
return nextSchema;
|
|
943
|
+
};
|
|
944
|
+
/**
|
|
675
945
|
* Build a Prisma model-level @@index definition line.
|
|
676
946
|
*
|
|
677
947
|
* @param index The schema index definition to convert to a Prisma \@\@index line.
|
|
@@ -873,8 +1143,9 @@ const findModelBlock = (schema, table) => {
|
|
|
873
1143
|
*/
|
|
874
1144
|
const applyCreateTableOperation = (schema, operation) => {
|
|
875
1145
|
if (findModelBlock(schema, operation.table)) throw new ArkormException(`Prisma model for table [${operation.table}] already exists.`);
|
|
1146
|
+
const schemaWithEnums = ensureEnumBlocks(schema, operation.columns);
|
|
876
1147
|
const block = buildModelBlock(operation);
|
|
877
|
-
return applyInverseRelations(`${
|
|
1148
|
+
return applyInverseRelations(`${schemaWithEnums.trimEnd()}\n\n${block}\n`, toModelName(operation.table), operation.foreignKeys ?? []);
|
|
878
1149
|
};
|
|
879
1150
|
/**
|
|
880
1151
|
* Apply an alter table operation to a Prisma schema string, modifying the model
|
|
@@ -887,7 +1158,10 @@ const applyCreateTableOperation = (schema, operation) => {
|
|
|
887
1158
|
const applyAlterTableOperation = (schema, operation) => {
|
|
888
1159
|
const model = findModelBlock(schema, operation.table);
|
|
889
1160
|
if (!model) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
|
|
890
|
-
|
|
1161
|
+
const schemaWithEnums = ensureEnumBlocks(schema, operation.addColumns);
|
|
1162
|
+
const refreshedModel = findModelBlock(schemaWithEnums, operation.table);
|
|
1163
|
+
if (!refreshedModel) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
|
|
1164
|
+
let block = refreshedModel.block;
|
|
891
1165
|
const bodyLines = block.split("\n");
|
|
892
1166
|
operation.dropColumns.forEach((column) => {
|
|
893
1167
|
const columnRegex = new RegExp(`^\\s*${escapeRegex(column)}\\s+`);
|
|
@@ -917,7 +1191,7 @@ const applyAlterTableOperation = (schema, operation) => {
|
|
|
917
1191
|
injectLineIntoModelBody(bodyLines, relationLine, (line) => relationRegex.test(line));
|
|
918
1192
|
}
|
|
919
1193
|
block = bodyLines.join("\n");
|
|
920
|
-
return applyInverseRelations(`${
|
|
1194
|
+
return applyInverseRelations(`${schemaWithEnums.slice(0, refreshedModel.start)}${block}${schemaWithEnums.slice(refreshedModel.end)}`, model.modelName, operation.addForeignKeys ?? []);
|
|
921
1195
|
};
|
|
922
1196
|
/**
|
|
923
1197
|
* Apply a drop table operation to a Prisma schema string, removing the model block
|