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