From a540558f17100826d9c8e5b94f9939300393b954 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sat, 15 Mar 2025 10:16:54 +0000 Subject: [PATCH 1/7] Support for links for policies with variable as 2nd argument Fixes N1ebieski/vs-code-extension#23 --- src/features/auth.ts | 3 +++ src/repositories/models.ts | 20 ++++++++++++++++++++ src/support/str.ts | 12 ++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 src/support/str.ts diff --git a/src/features/auth.ts b/src/features/auth.ts index cb8d127c..87040ae5 100644 --- a/src/features/auth.ts +++ b/src/features/auth.ts @@ -1,6 +1,7 @@ import { notFound } from "@src/diagnostic"; import AutocompleteResult from "@src/parser/AutocompleteResult"; import { AuthItem, getPolicies } from "@src/repositories/auth"; +import { getModelByVariable } from "@src/repositories/models"; import { config } from "@src/support/config"; import { findHoverMatchesInDoc } from "@src/support/doc"; import { detectedRange, detectInDoc } from "@src/support/parser"; @@ -130,6 +131,8 @@ const analyzeParam = ( if (nextArg?.type === "array") { classArg = nextArg.children[0]?.value?.className; + } else if (nextArg?.type === "variable") { + classArg = getModelByVariable(nextArg.name)?.class ?? null; } else { classArg = nextArg?.className; } diff --git a/src/repositories/models.ts b/src/repositories/models.ts index 3d045a3c..7a05d940 100644 --- a/src/repositories/models.ts +++ b/src/repositories/models.ts @@ -1,3 +1,4 @@ +import { camel, snake } from "@src/support/str"; import { repository } from "."; import { Eloquent } from ".."; import { writeEloquentDocBlocks } from "../support/docblocks"; @@ -22,6 +23,25 @@ const load = () => { }); }; +export const getModelByVariable = (variable: string): Eloquent.Model | undefined => { + const model = Object.entries(getModels().items).find(([key]) => { + const modelName = key.split("\\").pop(); + + if (!modelName) { + return undefined; + } + + return [ + modelName, + modelName.toLowerCase(), + camel(modelName), + snake(modelName) + ].includes(variable); + }); + + return model?.[1]; +}; + export const getModels = repository({ load, pattern: modelPaths diff --git a/src/support/str.ts b/src/support/str.ts new file mode 100644 index 00000000..6a68bc17 --- /dev/null +++ b/src/support/str.ts @@ -0,0 +1,12 @@ +export const camel = (str: string): string => { + return str + .replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '') // Removing separators and converting to uppercase + .replace(/^(.)/, (c) => c.toLowerCase()); // First letter lowercase +}; + +export const snake = (str: string): string => { + return str + .replace(/([a-z])([A-Z])/g, '$1_$2') // Separation of camelCase + .replace(/[-\s]+/g, '_') // Converting spaces and dashes to underscores + .toLowerCase(); +}; From 84482d24d01f839854e24218a769a356a21ab0ec Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sat, 15 Mar 2025 10:40:03 +0000 Subject: [PATCH 2/7] refactoring --- src/features/auth.ts | 4 ++-- src/repositories/models.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/features/auth.ts b/src/features/auth.ts index 87040ae5..c85eea1c 100644 --- a/src/features/auth.ts +++ b/src/features/auth.ts @@ -1,7 +1,7 @@ import { notFound } from "@src/diagnostic"; import AutocompleteResult from "@src/parser/AutocompleteResult"; import { AuthItem, getPolicies } from "@src/repositories/auth"; -import { getModelByVariable } from "@src/repositories/models"; +import { getModelByName } from "@src/repositories/models"; import { config } from "@src/support/config"; import { findHoverMatchesInDoc } from "@src/support/doc"; import { detectedRange, detectInDoc } from "@src/support/parser"; @@ -132,7 +132,7 @@ const analyzeParam = ( if (nextArg?.type === "array") { classArg = nextArg.children[0]?.value?.className; } else if (nextArg?.type === "variable") { - classArg = getModelByVariable(nextArg.name)?.class ?? null; + classArg = getModelByName(nextArg.name)?.class ?? null; } else { classArg = nextArg?.className; } diff --git a/src/repositories/models.ts b/src/repositories/models.ts index 7a05d940..3ae2cd8b 100644 --- a/src/repositories/models.ts +++ b/src/repositories/models.ts @@ -23,7 +23,7 @@ const load = () => { }); }; -export const getModelByVariable = (variable: string): Eloquent.Model | undefined => { +export const getModelByName = (name: string): Eloquent.Model | undefined => { const model = Object.entries(getModels().items).find(([key]) => { const modelName = key.split("\\").pop(); @@ -36,7 +36,7 @@ export const getModelByVariable = (variable: string): Eloquent.Model | undefined modelName.toLowerCase(), camel(modelName), snake(modelName) - ].includes(variable); + ].includes(name); }); return model?.[1]; From f2a6e2a806036f529520739ba7d3bb601d1c0543 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sat, 15 Mar 2025 13:04:44 +0000 Subject: [PATCH 3/7] fix for nextArg type array --- src/features/auth.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/features/auth.ts b/src/features/auth.ts index c85eea1c..7fe37c7e 100644 --- a/src/features/auth.ts +++ b/src/features/auth.ts @@ -127,24 +127,29 @@ const analyzeParam = ( // @ts-ignore const nextArg = item.arguments.children[1].children[0]; - let classArg: string | null = null; + let classArg = null; + let modelClass = null; if (nextArg?.type === "array") { - classArg = nextArg.children[0]?.value?.className; - } else if (nextArg?.type === "variable") { - classArg = getModelByName(nextArg.name)?.class ?? null; + classArg = nextArg.children[0]?.value; } else { - classArg = nextArg?.className; + classArg = nextArg; } - if (!classArg) { + if (classArg?.type === "variable") { + modelClass = getModelByName(classArg.name)?.class ?? null; + } else { + modelClass = classArg?.className; + } + + if (!modelClass) { // If it's not a class we can even identify, just ignore it return { missingReason: "ignored", }; } - const found = policies.find((items) => items.model === classArg); + const found = policies.find((items) => items.model === modelClass); if (!found) { return { From b961dfc8555714044961b664e3f94d7fb637367c Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sat, 15 Mar 2025 13:15:42 +0000 Subject: [PATCH 4/7] refactoring --- src/features/auth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/auth.ts b/src/features/auth.ts index 7fe37c7e..d659a83a 100644 --- a/src/features/auth.ts +++ b/src/features/auth.ts @@ -128,7 +128,7 @@ const analyzeParam = ( // @ts-ignore const nextArg = item.arguments.children[1].children[0]; let classArg = null; - let modelClass = null; + let modelClass: string | null = null; if (nextArg?.type === "array") { classArg = nextArg.children[0]?.value; From 980bd67c99a1dc9001653c56276e9044ed216ad7 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sat, 15 Mar 2025 17:29:00 +0000 Subject: [PATCH 5/7] refactoring --- src/features/auth.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/features/auth.ts b/src/features/auth.ts index d659a83a..ec63c14d 100644 --- a/src/features/auth.ts +++ b/src/features/auth.ts @@ -127,20 +127,12 @@ const analyzeParam = ( // @ts-ignore const nextArg = item.arguments.children[1].children[0]; - let classArg = null; - let modelClass: string | null = null; - if (nextArg?.type === "array") { - classArg = nextArg.children[0]?.value; - } else { - classArg = nextArg; - } + const classArg = nextArg?.type === "array" ? + nextArg.children[0]?.value : nextArg; - if (classArg?.type === "variable") { - modelClass = getModelByName(classArg.name)?.class ?? null; - } else { - modelClass = classArg?.className; - } + const modelClass = classArg?.type === "variable" ? + getModelByName(classArg.name)?.class : classArg?.className; if (!modelClass) { // If it's not a class we can even identify, just ignore it From 8f60fa87a74837aececfd8fd346cb6b598789ff4 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Fri, 11 Apr 2025 07:49:36 +0000 Subject: [PATCH 6/7] Move name cases (camel, snake etc.) from javascript support helpers to the model php template --- php-templates/models.php | 17 +++++++++++++++++ src/index.d.ts | 2 ++ src/repositories/models.ts | 15 ++------------- src/support/str.ts | 12 ------------ src/templates/models.ts | 17 +++++++++++++++++ 5 files changed, 38 insertions(+), 25 deletions(-) delete mode 100644 src/support/str.ts diff --git a/php-templates/models.php b/php-templates/models.php index 3946d402..fb61b82f 100644 --- a/php-templates/models.php +++ b/php-templates/models.php @@ -144,11 +144,14 @@ protected function getInfo($className) $data["extends"] = $this->getParentClass($reflection); + $data['name_cases'] = $this->getNameCases(str($className)->afterLast('\\')->toString()); + $existingProperties = $this->collectExistingProperties($reflection); $data['attributes'] = collect($data['attributes']) ->map(fn($attrs) => array_merge($attrs, [ 'title_case' => str($attrs['name'])->title()->replace('_', '')->toString(), + 'name_cases' => $this->getNameCases($attrs['name']), 'documented' => $existingProperties->contains($attrs['name']), 'cast' => $this->getCastReturnType($attrs['cast']) ])) @@ -166,6 +169,20 @@ protected function getInfo($className) $className => $data, ]; } + + /** + * @return array + */ + protected function getNameCases(string $name): array + { + return collect([ + $name, + str($name)->camel()->toString(), + str($name)->snake()->toString(), + str($name)->studly()->toString(), + str($name)->studly()->lower()->toString(), + ])->unique()->values()->toArray(); + } }; $builder = new class($docblocks) { diff --git a/src/index.d.ts b/src/index.d.ts index dbc537e8..0b7650de 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -83,6 +83,7 @@ declare namespace Eloquent { observers: Observer[]; scopes: string[]; extends: string | null; + name_cases: string[]; } interface Attribute { @@ -97,6 +98,7 @@ declare namespace Eloquent { appended: null; cast: string | null; title_case: string; + name_cases: string[]; documented: boolean; } diff --git a/src/repositories/models.ts b/src/repositories/models.ts index 3ae2cd8b..28dbb934 100644 --- a/src/repositories/models.ts +++ b/src/repositories/models.ts @@ -24,19 +24,8 @@ const load = () => { }; export const getModelByName = (name: string): Eloquent.Model | undefined => { - const model = Object.entries(getModels().items).find(([key]) => { - const modelName = key.split("\\").pop(); - - if (!modelName) { - return undefined; - } - - return [ - modelName, - modelName.toLowerCase(), - camel(modelName), - snake(modelName) - ].includes(name); + const model = Object.entries(getModels().items).find(([, value]) => { + return value.name_cases.includes(name); }); return model?.[1]; diff --git a/src/support/str.ts b/src/support/str.ts deleted file mode 100644 index 6a68bc17..00000000 --- a/src/support/str.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const camel = (str: string): string => { - return str - .replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '') // Removing separators and converting to uppercase - .replace(/^(.)/, (c) => c.toLowerCase()); // First letter lowercase -}; - -export const snake = (str: string): string => { - return str - .replace(/([a-z])([A-Z])/g, '$1_$2') // Separation of camelCase - .replace(/[-\s]+/g, '_') // Converting spaces and dashes to underscores - .toLowerCase(); -}; diff --git a/src/templates/models.ts b/src/templates/models.ts index 158b4952..61ff600a 100644 --- a/src/templates/models.ts +++ b/src/templates/models.ts @@ -144,11 +144,14 @@ $models = new class($factory) { $data["extends"] = $this->getParentClass($reflection); + $data['name_cases'] = $this->getNameCases(str($className)->afterLast('\\\\')->toString()); + $existingProperties = $this->collectExistingProperties($reflection); $data['attributes'] = collect($data['attributes']) ->map(fn($attrs) => array_merge($attrs, [ 'title_case' => str($attrs['name'])->title()->replace('_', '')->toString(), + 'name_cases' => $this->getNameCases($attrs['name']), 'documented' => $existingProperties->contains($attrs['name']), 'cast' => $this->getCastReturnType($attrs['cast']) ])) @@ -166,6 +169,20 @@ $models = new class($factory) { $className => $data, ]; } + + /** + * @return array + */ + protected function getNameCases(string $name): array + { + return collect([ + $name, + str($name)->camel()->toString(), + str($name)->snake()->toString(), + str($name)->studly()->toString(), + str($name)->studly()->lower()->toString(), + ])->unique()->values()->toArray(); + } }; $builder = new class($docblocks) { From c7dc243c60d6392fe07104156e526af790681c53 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Fri, 11 Apr 2025 09:16:08 +0000 Subject: [PATCH 7/7] refactoring --- src/repositories/models.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/repositories/models.ts b/src/repositories/models.ts index 28dbb934..411618ce 100644 --- a/src/repositories/models.ts +++ b/src/repositories/models.ts @@ -1,4 +1,3 @@ -import { camel, snake } from "@src/support/str"; import { repository } from "."; import { Eloquent } from ".."; import { writeEloquentDocBlocks } from "../support/docblocks";