Skip to content

Commit f0848a0

Browse files
Merge pull request #258 from freerkminnema/eloquent-docblocks
Improvements to Eloquent docblocks
2 parents 727326b + fb3afce commit f0848a0

File tree

1 file changed

+67
-32
lines changed

1 file changed

+67
-32
lines changed

src/support/docblocks.ts

Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -199,54 +199,89 @@ const getAttributeBlocks = (
199199
};
200200

201201
const getAttributeType = (attr: Eloquent.Attribute): string => {
202-
const type = getActualType(attr.cast || attr.type);
202+
const type = getActualType(attr.cast, attr.type);
203203

204-
return attr.nullable ? `${type}|null` : type;
204+
if (attr.nullable && type !== "mixed") {
205+
return `${type}|null`;
206+
}
207+
208+
return type;
209+
};
210+
211+
type TypeMapping = Record<string, (string | RegExp)[]>;
212+
213+
const castMapping: TypeMapping = {
214+
array: ["json", "encrypted:json", "encrypted:array"],
215+
int: ["timestamp"],
216+
mixed: ["attribute", "accessor", "encrypted"],
217+
object: ["encrypted:object"],
218+
string: ["hashed"],
219+
"\\Illuminate\\Support\\Carbon": ["date", "datetime"],
220+
"\\Illuminate\\Support\\Collection": ["encrypted:collection"],
205221
};
206222

207-
const mapType = (type: string): string => {
208-
const mapping: Record<string, (string | RegExp)[]> = {
209-
bool: [
210-
"boolean(1)",
211-
"boolean(0)",
212-
"tinyint",
213-
"tinyint unsigned",
214-
"boolean",
215-
/tinyint\(\d+\)/,
216-
],
217-
string: [
218-
"longtext",
219-
"mediumtext",
220-
"text",
221-
/varchar\(\d+\)/,
222-
/char\(\d+\)/,
223-
],
224-
float: [/double\(\d+\,\d+\)/],
225-
int: ["bigint", "bigint unsigned", "integer", "int unsigned"],
226-
mixed: ["attribute", "accessor", "encrypted"],
227-
array: ["encrypted:json", "encrypted:array", "json"],
228-
"\\Illuminate\\Support\\Carbon": ["datetime", "timestamp"],
229-
"\\Illuminate\\Support\\Collection": ["encrypted:collection"],
230-
object: ["encrypted:object"],
231-
};
223+
const typeMapping: TypeMapping = {
224+
bool: [/^boolean(\((0|1)\))?$/, /^tinyint( unsigned)?(\(\d+\))?$/],
225+
float: [
226+
"real",
227+
"money",
228+
"double precision",
229+
/^(double|decimal|numeric)(\(\d+\,\d+\))?$/,
230+
],
231+
int: [/^(big)?serial$/, /^(small|big)?int(eger)?( unsigned)?$/],
232+
resource: ["bytea"],
233+
string: [
234+
"box",
235+
"cidr",
236+
"inet",
237+
"line",
238+
"lseg",
239+
"path",
240+
"time",
241+
"uuid",
242+
"year",
243+
"point",
244+
"circle",
245+
"polygon",
246+
"interval",
247+
/^json(b)?$/,
248+
/^date(time)?$/,
249+
/^macaddr(8)?$/,
250+
/^(long|medium)?text$/,
251+
/^(var)?char(acter)?( varying)??(\(\d+\))?$/,
252+
/^time(stamp)?(\(\d+\))?( (with|without) time zone)?$/,
253+
],
254+
};
255+
256+
const findInMapping = (
257+
mapping: TypeMapping,
258+
value: string | null,
259+
): string | null => {
260+
if (value === null) {
261+
return null;
262+
}
232263

233264
for (const [newType, matches] of Object.entries(mapping)) {
234265
for (const match of matches) {
235-
if (type === match) {
266+
if (match === value) {
236267
return newType;
237268
}
238269

239-
if (match instanceof RegExp && type.match(match)) {
270+
if (match instanceof RegExp && value.match(match)) {
240271
return newType;
241272
}
242273
}
243274
}
244275

245-
return type;
276+
return null;
246277
};
247278

248-
const getActualType = (type: string): string => {
249-
const finalType = mapType(type);
279+
const getActualType = (cast: string | null, type: string): string => {
280+
const finalType =
281+
findInMapping(castMapping, cast) ||
282+
cast ||
283+
findInMapping(typeMapping, type) ||
284+
"mixed";
250285

251286
if (finalType.includes("\\") && !finalType.startsWith("\\")) {
252287
return `\\${finalType}`;

0 commit comments

Comments
 (0)