@famgia/omnify-laravel 0.0.78 → 0.0.79

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
@@ -24,7 +24,7 @@ import {
24
24
  schemaToBlueprint,
25
25
  toColumnName,
26
26
  toTableName
27
- } from "./chunk-FEHKJQMT.js";
27
+ } from "./chunk-6QYGCK3D.js";
28
28
  export {
29
29
  formatColumnMethod,
30
30
  formatForeignKey,
package/dist/plugin.cjs CHANGED
@@ -2497,6 +2497,608 @@ function getFactoryPath(factory) {
2497
2497
  return factory.path;
2498
2498
  }
2499
2499
 
2500
+ // src/request/generator.ts
2501
+ var import_omnify_types3 = require("@famgia/omnify-types");
2502
+ var DEFAULT_OPTIONS2 = {
2503
+ baseRequestNamespace: "App\\Http\\Requests\\OmnifyBase",
2504
+ requestNamespace: "App\\Http\\Requests",
2505
+ baseRequestPath: "app/Http/Requests/OmnifyBase",
2506
+ requestPath: "app/Http/Requests",
2507
+ modelNamespace: "App\\Models",
2508
+ customTypes: /* @__PURE__ */ new Map(),
2509
+ locale: "en"
2510
+ };
2511
+ var SKIP_FIELDS = /* @__PURE__ */ new Set([
2512
+ "id",
2513
+ "created_at",
2514
+ "updated_at",
2515
+ "deleted_at",
2516
+ "remember_token",
2517
+ "email_verified_at"
2518
+ ]);
2519
+ function resolveOptions3(options) {
2520
+ return {
2521
+ baseRequestNamespace: options?.baseRequestNamespace ?? DEFAULT_OPTIONS2.baseRequestNamespace,
2522
+ requestNamespace: options?.requestNamespace ?? DEFAULT_OPTIONS2.requestNamespace,
2523
+ baseRequestPath: options?.baseRequestPath ?? DEFAULT_OPTIONS2.baseRequestPath,
2524
+ requestPath: options?.requestPath ?? DEFAULT_OPTIONS2.requestPath,
2525
+ modelNamespace: options?.modelNamespace ?? DEFAULT_OPTIONS2.modelNamespace,
2526
+ customTypes: options?.customTypes ?? /* @__PURE__ */ new Map(),
2527
+ locale: options?.locale ?? DEFAULT_OPTIONS2.locale
2528
+ };
2529
+ }
2530
+ function escapePhpString2(str) {
2531
+ return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
2532
+ }
2533
+ function getDisplayName(displayName, locale, fallback) {
2534
+ if (!displayName) return fallback;
2535
+ if (typeof displayName === "string") return displayName;
2536
+ if ((0, import_omnify_types3.isLocaleMap)(displayName)) {
2537
+ return displayName[locale] ?? displayName["en"] ?? fallback;
2538
+ }
2539
+ return fallback;
2540
+ }
2541
+ function getModuleName(schema) {
2542
+ if (schema.module) {
2543
+ return schema.module;
2544
+ }
2545
+ return "";
2546
+ }
2547
+ function generateStoreRules(propName, propDef, schema, schemas, options) {
2548
+ const rules = [];
2549
+ const snakeName = toSnakeCase(propName);
2550
+ const prop = propDef;
2551
+ const tableName = schema.options?.tableName ?? pluralize(toSnakeCase(schema.name));
2552
+ const isNullable2 = prop.nullable === true;
2553
+ if (!isNullable2) {
2554
+ rules.push("'required'");
2555
+ } else {
2556
+ rules.push("'nullable'");
2557
+ }
2558
+ switch (propDef.type) {
2559
+ case "String":
2560
+ case "Email":
2561
+ case "Password":
2562
+ rules.push("'string'");
2563
+ const length = prop.length ?? 255;
2564
+ rules.push(`'max:${length}'`);
2565
+ if (propDef.type === "Email") {
2566
+ rules.push("'email'");
2567
+ }
2568
+ break;
2569
+ case "Text":
2570
+ case "MediumText":
2571
+ case "LongText":
2572
+ rules.push("'string'");
2573
+ break;
2574
+ case "TinyInt":
2575
+ case "Int":
2576
+ case "BigInt":
2577
+ rules.push("'integer'");
2578
+ if (prop.min !== void 0) {
2579
+ rules.push(`'min:${prop.min}'`);
2580
+ }
2581
+ if (prop.max !== void 0) {
2582
+ rules.push(`'max:${prop.max}'`);
2583
+ }
2584
+ break;
2585
+ case "Float":
2586
+ case "Decimal":
2587
+ rules.push("'numeric'");
2588
+ if (prop.min !== void 0) {
2589
+ rules.push(`'min:${prop.min}'`);
2590
+ }
2591
+ if (prop.max !== void 0) {
2592
+ rules.push(`'max:${prop.max}'`);
2593
+ }
2594
+ break;
2595
+ case "Boolean":
2596
+ rules.push("'boolean'");
2597
+ break;
2598
+ case "Date":
2599
+ rules.push("'date'");
2600
+ break;
2601
+ case "DateTime":
2602
+ case "Timestamp":
2603
+ rules.push("'date'");
2604
+ break;
2605
+ case "Json":
2606
+ rules.push("'array'");
2607
+ break;
2608
+ case "Enum":
2609
+ case "EnumRef":
2610
+ rules.push("'string'");
2611
+ if (prop.enum && Array.isArray(prop.enum)) {
2612
+ const values = prop.enum.map((v) => `'${v}'`).join(", ");
2613
+ rules.push(`Rule::in([${values}])`);
2614
+ }
2615
+ break;
2616
+ case "Association":
2617
+ const assoc = propDef;
2618
+ if (assoc.relation === "ManyToOne" || assoc.relation === "OneToOne") {
2619
+ if (assoc.target) {
2620
+ const targetSchema = schemas[assoc.target];
2621
+ const targetTable = targetSchema?.options?.tableName ?? pluralize(toSnakeCase(assoc.target));
2622
+ rules.push("'integer'");
2623
+ rules.push(`'exists:${targetTable},id'`);
2624
+ }
2625
+ }
2626
+ break;
2627
+ }
2628
+ if (prop.unique === true) {
2629
+ rules.push(`'unique:${tableName}'`);
2630
+ }
2631
+ return rules;
2632
+ }
2633
+ function generateUpdateRules(propName, propDef, schema, schemas, options) {
2634
+ const rules = [];
2635
+ const snakeName = toSnakeCase(propName);
2636
+ const prop = propDef;
2637
+ const tableName = schema.options?.tableName ?? pluralize(toSnakeCase(schema.name));
2638
+ const modelVar = toSnakeCase(schema.name);
2639
+ rules.push("'sometimes'");
2640
+ switch (propDef.type) {
2641
+ case "String":
2642
+ case "Email":
2643
+ case "Password":
2644
+ rules.push("'string'");
2645
+ const length = prop.length ?? 255;
2646
+ rules.push(`'max:${length}'`);
2647
+ if (propDef.type === "Email") {
2648
+ rules.push("'email'");
2649
+ }
2650
+ break;
2651
+ case "Text":
2652
+ case "MediumText":
2653
+ case "LongText":
2654
+ rules.push("'string'");
2655
+ break;
2656
+ case "TinyInt":
2657
+ case "Int":
2658
+ case "BigInt":
2659
+ rules.push("'integer'");
2660
+ if (prop.min !== void 0) {
2661
+ rules.push(`'min:${prop.min}'`);
2662
+ }
2663
+ if (prop.max !== void 0) {
2664
+ rules.push(`'max:${prop.max}'`);
2665
+ }
2666
+ break;
2667
+ case "Float":
2668
+ case "Decimal":
2669
+ rules.push("'numeric'");
2670
+ if (prop.min !== void 0) {
2671
+ rules.push(`'min:${prop.min}'`);
2672
+ }
2673
+ if (prop.max !== void 0) {
2674
+ rules.push(`'max:${prop.max}'`);
2675
+ }
2676
+ break;
2677
+ case "Boolean":
2678
+ rules.push("'boolean'");
2679
+ break;
2680
+ case "Date":
2681
+ rules.push("'date'");
2682
+ break;
2683
+ case "DateTime":
2684
+ case "Timestamp":
2685
+ rules.push("'date'");
2686
+ break;
2687
+ case "Json":
2688
+ rules.push("'array'");
2689
+ break;
2690
+ case "Enum":
2691
+ case "EnumRef":
2692
+ rules.push("'string'");
2693
+ if (prop.enum && Array.isArray(prop.enum)) {
2694
+ const values = prop.enum.map((v) => `'${v}'`).join(", ");
2695
+ rules.push(`Rule::in([${values}])`);
2696
+ }
2697
+ break;
2698
+ case "Association":
2699
+ const assoc = propDef;
2700
+ if (assoc.relation === "ManyToOne" || assoc.relation === "OneToOne") {
2701
+ if (assoc.target) {
2702
+ const targetSchema = schemas[assoc.target];
2703
+ const targetTable = targetSchema?.options?.tableName ?? pluralize(toSnakeCase(assoc.target));
2704
+ rules.push("'integer'");
2705
+ rules.push(`'exists:${targetTable},id'`);
2706
+ }
2707
+ }
2708
+ break;
2709
+ }
2710
+ if (prop.unique === true) {
2711
+ rules.push(`Rule::unique('${tableName}')->ignore($this->route('${modelVar}'))`);
2712
+ }
2713
+ return rules;
2714
+ }
2715
+ function expandCompoundTypeFields(propName, propDef, options) {
2716
+ const typeDef = options.customTypes.get(propDef.type);
2717
+ if (!typeDef || !typeDef.compound || !typeDef.expand) {
2718
+ return [];
2719
+ }
2720
+ const snakeName = toSnakeCase(propName);
2721
+ const prop = propDef;
2722
+ const isNullable2 = prop.nullable === true;
2723
+ const fields = [];
2724
+ for (const field of typeDef.expand) {
2725
+ const suffixSnake = toSnakeCase(field.suffix);
2726
+ const fieldName = `${snakeName}_${suffixSnake}`;
2727
+ const fieldOverride = prop.fields?.[field.suffix];
2728
+ const fieldNullable = fieldOverride?.nullable ?? isNullable2;
2729
+ const rules = [];
2730
+ if (!fieldNullable) {
2731
+ rules.push("'required'");
2732
+ } else {
2733
+ rules.push("'nullable'");
2734
+ }
2735
+ rules.push("'string'");
2736
+ const fieldAny = field;
2737
+ const length = fieldAny.laravel?.length ?? 255;
2738
+ rules.push(`'max:${length}'`);
2739
+ fields.push({ fieldName, rules });
2740
+ }
2741
+ return fields;
2742
+ }
2743
+ function generateStoreRequestBase(schema, schemas, options) {
2744
+ const className = toPascalCase(schema.name);
2745
+ const module2 = getModuleName(schema);
2746
+ const namespaceModule = module2 ? `\\${module2}` : "";
2747
+ const namespace = `${options.baseRequestNamespace}${namespaceModule}`;
2748
+ const properties = schema.properties ?? {};
2749
+ const rulesLines = [];
2750
+ const attributeLines = [];
2751
+ const fieldList = [];
2752
+ let needsRuleImport = false;
2753
+ for (const [propName, propDef] of Object.entries(properties)) {
2754
+ const snakeName = toSnakeCase(propName);
2755
+ if (SKIP_FIELDS.has(snakeName)) continue;
2756
+ if (propDef.type === "Association") {
2757
+ const assoc = propDef;
2758
+ if (assoc.relation !== "ManyToOne" && assoc.relation !== "OneToOne") {
2759
+ continue;
2760
+ }
2761
+ const fkName = `${snakeName}_id`;
2762
+ const rules2 = generateStoreRules(propName, propDef, schema, schemas, options);
2763
+ if (rules2.some((r) => r.includes("Rule::"))) needsRuleImport = true;
2764
+ rulesLines.push(` '${fkName}' => [${rules2.join(", ")}],`);
2765
+ fieldList.push(fkName);
2766
+ const displayName2 = getDisplayName(propDef.displayName, options.locale, propName);
2767
+ attributeLines.push(` '${fkName}' => '${escapePhpString2(displayName2)}',`);
2768
+ continue;
2769
+ }
2770
+ const expandedFields = expandCompoundTypeFields(propName, propDef, options);
2771
+ if (expandedFields.length > 0) {
2772
+ for (const field of expandedFields) {
2773
+ rulesLines.push(` '${field.fieldName}' => [${field.rules.join(", ")}],`);
2774
+ fieldList.push(field.fieldName);
2775
+ attributeLines.push(` '${field.fieldName}' => '${escapePhpString2(field.fieldName)}',`);
2776
+ }
2777
+ continue;
2778
+ }
2779
+ const rules = generateStoreRules(propName, propDef, schema, schemas, options);
2780
+ if (rules.some((r) => r.includes("Rule::"))) needsRuleImport = true;
2781
+ rulesLines.push(` '${snakeName}' => [${rules.join(", ")}],`);
2782
+ fieldList.push(snakeName);
2783
+ const displayName = getDisplayName(propDef.displayName, options.locale, propName);
2784
+ attributeLines.push(` '${snakeName}' => '${escapePhpString2(displayName)}',`);
2785
+ }
2786
+ const ruleImport = needsRuleImport ? "\nuse Illuminate\\Validation\\Rule;" : "";
2787
+ const content = `<?php
2788
+
2789
+ /**
2790
+ * AUTO-GENERATED BY OMNIFY - DO NOT EDIT!
2791
+ *
2792
+ * This file is generated from Omnify schema: ${schema.name}
2793
+ * Re-run \`npx omnify generate\` to update.
2794
+ *
2795
+ * @generated
2796
+ */
2797
+
2798
+ namespace ${namespace};
2799
+
2800
+ use Illuminate\\Foundation\\Http\\FormRequest;${ruleImport}
2801
+
2802
+ abstract class ${className}StoreRequestBase extends FormRequest
2803
+ {
2804
+ /**
2805
+ * Validation rules generated from Omnify schema.
2806
+ *
2807
+ * Generated fields: ${fieldList.join(", ")}
2808
+ *
2809
+ * @return array<string, array<int, mixed>>
2810
+ */
2811
+ protected function schemaRules(): array
2812
+ {
2813
+ return [
2814
+ ${rulesLines.join("\n")}
2815
+ ];
2816
+ }
2817
+
2818
+ /**
2819
+ * Get custom attributes for validator errors.
2820
+ *
2821
+ * @return array<string, string>
2822
+ */
2823
+ protected function schemaAttributes(): array
2824
+ {
2825
+ return [
2826
+ ${attributeLines.join("\n")}
2827
+ ];
2828
+ }
2829
+ }
2830
+ `;
2831
+ const modulePath = module2 ? `/${module2}` : "";
2832
+ return {
2833
+ path: `${options.baseRequestPath}${modulePath}/${className}StoreRequestBase.php`,
2834
+ content,
2835
+ type: "store-base",
2836
+ overwrite: true,
2837
+ schemaName: schema.name,
2838
+ module: module2
2839
+ };
2840
+ }
2841
+ function generateUpdateRequestBase(schema, schemas, options) {
2842
+ const className = toPascalCase(schema.name);
2843
+ const module2 = getModuleName(schema);
2844
+ const namespaceModule = module2 ? `\\${module2}` : "";
2845
+ const namespace = `${options.baseRequestNamespace}${namespaceModule}`;
2846
+ const properties = schema.properties ?? {};
2847
+ const rulesLines = [];
2848
+ const attributeLines = [];
2849
+ let needsRuleImport = false;
2850
+ for (const [propName, propDef] of Object.entries(properties)) {
2851
+ const snakeName = toSnakeCase(propName);
2852
+ if (SKIP_FIELDS.has(snakeName)) continue;
2853
+ if (propDef.type === "Association") {
2854
+ const assoc = propDef;
2855
+ if (assoc.relation !== "ManyToOne" && assoc.relation !== "OneToOne") {
2856
+ continue;
2857
+ }
2858
+ const fkName = `${snakeName}_id`;
2859
+ const rules2 = generateUpdateRules(propName, propDef, schema, schemas, options);
2860
+ if (rules2.some((r) => r.includes("Rule::") || r.includes("Rule::"))) needsRuleImport = true;
2861
+ rulesLines.push(` '${fkName}' => [${rules2.join(", ")}],`);
2862
+ const displayName2 = getDisplayName(propDef.displayName, options.locale, propName);
2863
+ attributeLines.push(` '${fkName}' => '${escapePhpString2(displayName2)}',`);
2864
+ continue;
2865
+ }
2866
+ const expandedFields = expandCompoundTypeFields(propName, propDef, options);
2867
+ if (expandedFields.length > 0) {
2868
+ for (const field of expandedFields) {
2869
+ const updateRules = field.rules.map((r) => r === "'required'" ? "'sometimes'" : r);
2870
+ rulesLines.push(` '${field.fieldName}' => [${updateRules.join(", ")}],`);
2871
+ attributeLines.push(` '${field.fieldName}' => '${escapePhpString2(field.fieldName)}',`);
2872
+ }
2873
+ continue;
2874
+ }
2875
+ const rules = generateUpdateRules(propName, propDef, schema, schemas, options);
2876
+ if (rules.some((r) => r.includes("Rule::") || r.includes("Rule::"))) needsRuleImport = true;
2877
+ rulesLines.push(` '${snakeName}' => [${rules.join(", ")}],`);
2878
+ const displayName = getDisplayName(propDef.displayName, options.locale, propName);
2879
+ attributeLines.push(` '${snakeName}' => '${escapePhpString2(displayName)}',`);
2880
+ }
2881
+ const ruleImport = needsRuleImport ? "\nuse Illuminate\\Validation\\Rule;" : "";
2882
+ const content = `<?php
2883
+
2884
+ /**
2885
+ * AUTO-GENERATED BY OMNIFY - DO NOT EDIT!
2886
+ *
2887
+ * This file is generated from Omnify schema: ${schema.name}
2888
+ * Re-run \`npx omnify generate\` to update.
2889
+ *
2890
+ * @generated
2891
+ */
2892
+
2893
+ namespace ${namespace};
2894
+
2895
+ use Illuminate\\Foundation\\Http\\FormRequest;${ruleImport}
2896
+
2897
+ abstract class ${className}UpdateRequestBase extends FormRequest
2898
+ {
2899
+ /**
2900
+ * Validation rules generated from Omnify schema.
2901
+ * All fields use 'sometimes' for partial updates.
2902
+ *
2903
+ * @return array<string, array<int, mixed>>
2904
+ */
2905
+ protected function schemaRules(): array
2906
+ {
2907
+ return [
2908
+ ${rulesLines.join("\n")}
2909
+ ];
2910
+ }
2911
+
2912
+ /**
2913
+ * Get custom attributes for validator errors.
2914
+ *
2915
+ * @return array<string, string>
2916
+ */
2917
+ protected function schemaAttributes(): array
2918
+ {
2919
+ return [
2920
+ ${attributeLines.join("\n")}
2921
+ ];
2922
+ }
2923
+ }
2924
+ `;
2925
+ const modulePath = module2 ? `/${module2}` : "";
2926
+ return {
2927
+ path: `${options.baseRequestPath}${modulePath}/${className}UpdateRequestBase.php`,
2928
+ content,
2929
+ type: "update-base",
2930
+ overwrite: true,
2931
+ schemaName: schema.name,
2932
+ module: module2
2933
+ };
2934
+ }
2935
+ function generateStoreRequest(schema, options) {
2936
+ const className = toPascalCase(schema.name);
2937
+ const module2 = getModuleName(schema);
2938
+ const namespaceModule = module2 ? `\\${module2}` : "";
2939
+ const namespace = `${options.requestNamespace}${namespaceModule}`;
2940
+ const baseNamespace = `${options.baseRequestNamespace}${namespaceModule}`;
2941
+ const content = `<?php
2942
+
2943
+ /**
2944
+ * ${className} Store Request
2945
+ *
2946
+ * SAFE TO EDIT - This file is never overwritten by Omnify.
2947
+ */
2948
+
2949
+ namespace ${namespace};
2950
+
2951
+ use ${baseNamespace}\\${className}StoreRequestBase;
2952
+
2953
+ class ${className}StoreRequest extends ${className}StoreRequestBase
2954
+ {
2955
+ /**
2956
+ * Determine if the user is authorized to make this request.
2957
+ */
2958
+ public function authorize(): bool
2959
+ {
2960
+ return true;
2961
+ }
2962
+
2963
+ /**
2964
+ * Get the validation rules that apply to the request.
2965
+ *
2966
+ * @return array<string, array<int, mixed>>
2967
+ */
2968
+ public function rules(): array
2969
+ {
2970
+ return array_merge($this->schemaRules(), [
2971
+ // Custom/override rules here
2972
+ ]);
2973
+ }
2974
+
2975
+ /**
2976
+ * Get custom attributes for validator errors.
2977
+ *
2978
+ * @return array<string, string>
2979
+ */
2980
+ public function attributes(): array
2981
+ {
2982
+ return array_merge($this->schemaAttributes(), [
2983
+ // Custom attributes here
2984
+ ]);
2985
+ }
2986
+
2987
+ /**
2988
+ * Get custom messages for validator errors.
2989
+ *
2990
+ * @return array<string, string>
2991
+ */
2992
+ public function messages(): array
2993
+ {
2994
+ return [
2995
+ // Custom messages here
2996
+ ];
2997
+ }
2998
+ }
2999
+ `;
3000
+ const modulePath = module2 ? `/${module2}` : "";
3001
+ return {
3002
+ path: `${options.requestPath}${modulePath}/${className}StoreRequest.php`,
3003
+ content,
3004
+ type: "store",
3005
+ overwrite: false,
3006
+ schemaName: schema.name,
3007
+ module: module2
3008
+ };
3009
+ }
3010
+ function generateUpdateRequest(schema, options) {
3011
+ const className = toPascalCase(schema.name);
3012
+ const module2 = getModuleName(schema);
3013
+ const namespaceModule = module2 ? `\\${module2}` : "";
3014
+ const namespace = `${options.requestNamespace}${namespaceModule}`;
3015
+ const baseNamespace = `${options.baseRequestNamespace}${namespaceModule}`;
3016
+ const content = `<?php
3017
+
3018
+ /**
3019
+ * ${className} Update Request
3020
+ *
3021
+ * SAFE TO EDIT - This file is never overwritten by Omnify.
3022
+ */
3023
+
3024
+ namespace ${namespace};
3025
+
3026
+ use ${baseNamespace}\\${className}UpdateRequestBase;
3027
+
3028
+ class ${className}UpdateRequest extends ${className}UpdateRequestBase
3029
+ {
3030
+ /**
3031
+ * Determine if the user is authorized to make this request.
3032
+ */
3033
+ public function authorize(): bool
3034
+ {
3035
+ return true;
3036
+ }
3037
+
3038
+ /**
3039
+ * Get the validation rules that apply to the request.
3040
+ *
3041
+ * @return array<string, array<int, mixed>>
3042
+ */
3043
+ public function rules(): array
3044
+ {
3045
+ return array_merge($this->schemaRules(), [
3046
+ // Custom/override rules here
3047
+ ]);
3048
+ }
3049
+
3050
+ /**
3051
+ * Get custom attributes for validator errors.
3052
+ *
3053
+ * @return array<string, string>
3054
+ */
3055
+ public function attributes(): array
3056
+ {
3057
+ return array_merge($this->schemaAttributes(), [
3058
+ // Custom attributes here
3059
+ ]);
3060
+ }
3061
+
3062
+ /**
3063
+ * Get custom messages for validator errors.
3064
+ *
3065
+ * @return array<string, string>
3066
+ */
3067
+ public function messages(): array
3068
+ {
3069
+ return [
3070
+ // Custom messages here
3071
+ ];
3072
+ }
3073
+ }
3074
+ `;
3075
+ const modulePath = module2 ? `/${module2}` : "";
3076
+ return {
3077
+ path: `${options.requestPath}${modulePath}/${className}UpdateRequest.php`,
3078
+ content,
3079
+ type: "update",
3080
+ overwrite: false,
3081
+ schemaName: schema.name,
3082
+ module: module2
3083
+ };
3084
+ }
3085
+ function generateRequests(schemas, options) {
3086
+ const resolved = resolveOptions3(options);
3087
+ const requests = [];
3088
+ for (const schema of Object.values(schemas)) {
3089
+ if (schema.kind === "enum") continue;
3090
+ if (schema.options?.hidden === true) continue;
3091
+ requests.push(generateStoreRequestBase(schema, schemas, resolved));
3092
+ requests.push(generateUpdateRequestBase(schema, schemas, resolved));
3093
+ requests.push(generateStoreRequest(schema, resolved));
3094
+ requests.push(generateUpdateRequest(schema, resolved));
3095
+ }
3096
+ return requests;
3097
+ }
3098
+ function getRequestPath(request) {
3099
+ return request.path;
3100
+ }
3101
+
2500
3102
  // src/plugin.ts
2501
3103
  function getExistingMigrationTables(migrationsDir) {
2502
3104
  const existingTables = /* @__PURE__ */ new Set();
@@ -2581,10 +3183,34 @@ var LARAVEL_CONFIG_SCHEMA = {
2581
3183
  description: "Laravel database connection name (optional)",
2582
3184
  placeholder: "mysql",
2583
3185
  group: "options"
3186
+ },
3187
+ {
3188
+ key: "requestsPath",
3189
+ type: "path",
3190
+ label: "Requests Path",
3191
+ description: "Directory for user-editable FormRequest files",
3192
+ default: "app/Http/Requests",
3193
+ group: "output"
3194
+ },
3195
+ {
3196
+ key: "baseRequestsPath",
3197
+ type: "path",
3198
+ label: "Base Requests Path",
3199
+ description: "Directory for auto-generated base FormRequest files",
3200
+ default: "app/Http/Requests/OmnifyBase",
3201
+ group: "output"
3202
+ },
3203
+ {
3204
+ key: "generateRequests",
3205
+ type: "boolean",
3206
+ label: "Generate Requests",
3207
+ description: "Generate Laravel FormRequest classes for validation",
3208
+ default: false,
3209
+ group: "options"
2584
3210
  }
2585
3211
  ]
2586
3212
  };
2587
- function resolveOptions3(options) {
3213
+ function resolveOptions4(options) {
2588
3214
  return {
2589
3215
  migrationsPath: options?.migrationsPath ?? "database/migrations/omnify",
2590
3216
  modelsPath: options?.modelsPath ?? "app/Models",
@@ -2597,11 +3223,16 @@ function resolveOptions3(options) {
2597
3223
  generateFactories: options?.generateFactories ?? true,
2598
3224
  fakerLocale: options?.fakerLocale ?? "en_US",
2599
3225
  connection: options?.connection,
2600
- timestamp: options?.timestamp
3226
+ timestamp: options?.timestamp,
3227
+ requestsPath: options?.requestsPath ?? "app/Http/Requests",
3228
+ baseRequestsPath: options?.baseRequestsPath ?? "app/Http/Requests/OmnifyBase",
3229
+ requestNamespace: options?.requestNamespace ?? "App\\Http\\Requests",
3230
+ baseRequestNamespace: options?.baseRequestNamespace ?? "App\\Http\\Requests\\OmnifyBase",
3231
+ generateRequests: options?.generateRequests ?? false
2601
3232
  };
2602
3233
  }
2603
3234
  function laravelPlugin(options) {
2604
- const resolved = resolveOptions3(options);
3235
+ const resolved = resolveOptions4(options);
2605
3236
  const migrationGenerator = {
2606
3237
  name: "laravel-migrations",
2607
3238
  description: "Generate Laravel migration files",
@@ -2773,6 +3404,33 @@ function laravelPlugin(options) {
2773
3404
  }));
2774
3405
  }
2775
3406
  };
3407
+ const requestGenerator = {
3408
+ name: "laravel-requests",
3409
+ description: "Generate Laravel FormRequest classes for validation",
3410
+ generate: async (ctx) => {
3411
+ const requestOptions = {
3412
+ requestNamespace: resolved.requestNamespace,
3413
+ baseRequestNamespace: resolved.baseRequestNamespace,
3414
+ requestPath: resolved.requestsPath,
3415
+ baseRequestPath: resolved.baseRequestsPath,
3416
+ modelNamespace: resolved.modelNamespace,
3417
+ customTypes: ctx.customTypes
3418
+ };
3419
+ const requests = generateRequests(ctx.schemas, requestOptions);
3420
+ return requests.map((request) => ({
3421
+ path: getRequestPath(request),
3422
+ content: request.content,
3423
+ type: "other",
3424
+ // Skip writing user requests if they already exist
3425
+ skipIfExists: !request.overwrite,
3426
+ metadata: {
3427
+ requestType: request.type,
3428
+ schemaName: request.schemaName,
3429
+ module: request.module
3430
+ }
3431
+ }));
3432
+ }
3433
+ };
2776
3434
  const generators = [migrationGenerator];
2777
3435
  if (resolved.generateModels) {
2778
3436
  generators.push(modelGenerator);
@@ -2780,6 +3438,9 @@ function laravelPlugin(options) {
2780
3438
  if (resolved.generateFactories) {
2781
3439
  generators.push(factoryGenerator);
2782
3440
  }
3441
+ if (resolved.generateRequests) {
3442
+ generators.push(requestGenerator);
3443
+ }
2783
3444
  return {
2784
3445
  name: "@famgia/omnify-laravel",
2785
3446
  version: "0.0.14",