@famgia/omnify-laravel 0.0.79 → 0.0.81
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/{chunk-6QYGCK3D.js → chunk-WFEVU3LX.js} +481 -15
- package/dist/chunk-WFEVU3LX.js.map +1 -0
- package/dist/index.cjs +480 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/plugin.cjs +480 -14
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +25 -0
- package/dist/plugin.d.ts +25 -0
- package/dist/plugin.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-6QYGCK3D.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -2308,7 +2308,8 @@ function resolveOptions2(options) {
|
|
|
2308
2308
|
return {
|
|
2309
2309
|
modelNamespace: options?.modelNamespace ?? "App\\Models",
|
|
2310
2310
|
factoryPath: options?.factoryPath ?? "database/factories",
|
|
2311
|
-
fakerLocale: options?.fakerLocale ?? "en_US"
|
|
2311
|
+
fakerLocale: options?.fakerLocale ?? "en_US",
|
|
2312
|
+
customTypes: options?.customTypes ?? /* @__PURE__ */ new Map()
|
|
2312
2313
|
};
|
|
2313
2314
|
}
|
|
2314
2315
|
function getStubContent2() {
|
|
@@ -2341,7 +2342,63 @@ class {{MODEL_NAME}}Factory extends Factory
|
|
|
2341
2342
|
}
|
|
2342
2343
|
`;
|
|
2343
2344
|
}
|
|
2344
|
-
function
|
|
2345
|
+
function generateJapaneseCompoundFake(propertyName, property, options) {
|
|
2346
|
+
const typeDef = options.customTypes.get(property.type);
|
|
2347
|
+
if (!typeDef || !typeDef.compound || !typeDef.expand) {
|
|
2348
|
+
return null;
|
|
2349
|
+
}
|
|
2350
|
+
const snakeName = toSnakeCase(propertyName);
|
|
2351
|
+
const lines = [];
|
|
2352
|
+
const jaFaker = "fake('ja_JP')";
|
|
2353
|
+
switch (property.type) {
|
|
2354
|
+
case "JapaneseName":
|
|
2355
|
+
lines.push(`'${snakeName}_lastname' => ${jaFaker}->lastName(),`);
|
|
2356
|
+
lines.push(`'${snakeName}_firstname' => ${jaFaker}->firstName(),`);
|
|
2357
|
+
lines.push(`'${snakeName}_kana_lastname' => ${jaFaker}->lastKanaName(),`);
|
|
2358
|
+
lines.push(`'${snakeName}_kana_firstname' => ${jaFaker}->firstKanaName(),`);
|
|
2359
|
+
break;
|
|
2360
|
+
case "JapaneseAddress":
|
|
2361
|
+
lines.push(`'${snakeName}_postal_code' => ${jaFaker}->postcode(),`);
|
|
2362
|
+
lines.push(`'${snakeName}_prefecture_id' => ${jaFaker}->numberBetween(1, 47),`);
|
|
2363
|
+
lines.push(`'${snakeName}_address1' => ${jaFaker}->city() . ${jaFaker}->ward(),`);
|
|
2364
|
+
lines.push(`'${snakeName}_address2' => ${jaFaker}->streetAddress(),`);
|
|
2365
|
+
lines.push(`'${snakeName}_address3' => ${jaFaker}->optional()->secondaryAddress(),`);
|
|
2366
|
+
break;
|
|
2367
|
+
case "JapaneseBankAccount":
|
|
2368
|
+
lines.push(`'${snakeName}_bank_code' => ${jaFaker}->regexify('[0-9]{4}'),`);
|
|
2369
|
+
lines.push(`'${snakeName}_branch_code' => ${jaFaker}->regexify('[0-9]{3}'),`);
|
|
2370
|
+
lines.push(`'${snakeName}_account_type' => ${jaFaker}->randomElement(['1', '2', '4']),`);
|
|
2371
|
+
lines.push(`'${snakeName}_account_number' => ${jaFaker}->regexify('[0-9]{7}'),`);
|
|
2372
|
+
lines.push(`'${snakeName}_account_holder' => ${jaFaker}->lastKanaName() . ' ' . ${jaFaker}->firstKanaName(),`);
|
|
2373
|
+
break;
|
|
2374
|
+
default:
|
|
2375
|
+
for (const field of typeDef.expand) {
|
|
2376
|
+
const suffixSnake = toSnakeCase(field.suffix);
|
|
2377
|
+
const fieldName = `${snakeName}_${suffixSnake}`;
|
|
2378
|
+
const sql = field.sql;
|
|
2379
|
+
if (sql?.sqlType === "TINYINT" || sql?.sqlType === "INT" || sql?.sqlType === "BIGINT") {
|
|
2380
|
+
lines.push(`'${fieldName}' => fake()->numberBetween(1, 100),`);
|
|
2381
|
+
} else {
|
|
2382
|
+
lines.push(`'${fieldName}' => fake()->words(2, true),`);
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
break;
|
|
2386
|
+
}
|
|
2387
|
+
return lines;
|
|
2388
|
+
}
|
|
2389
|
+
function generateJapaneseSimpleFake(propertyName, property) {
|
|
2390
|
+
const snakeName = toSnakeCase(propertyName);
|
|
2391
|
+
const jaFaker = "fake('ja_JP')";
|
|
2392
|
+
switch (property.type) {
|
|
2393
|
+
case "JapanesePhone":
|
|
2394
|
+
return `'${snakeName}' => ${jaFaker}->phoneNumber(),`;
|
|
2395
|
+
case "JapanesePostalCode":
|
|
2396
|
+
return `'${snakeName}' => ${jaFaker}->postcode(),`;
|
|
2397
|
+
default:
|
|
2398
|
+
return null;
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
function generateFakeData(propertyName, property, schema, schemas, options) {
|
|
2345
2402
|
const type = property.type;
|
|
2346
2403
|
if (["deleted_at", "created_at", "updated_at"].includes(propertyName)) {
|
|
2347
2404
|
return null;
|
|
@@ -2349,6 +2406,10 @@ function generateFakeData(propertyName, property, schema, schemas) {
|
|
|
2349
2406
|
if (type === "Association") {
|
|
2350
2407
|
return null;
|
|
2351
2408
|
}
|
|
2409
|
+
const japaneseFake = generateJapaneseSimpleFake(propertyName, property);
|
|
2410
|
+
if (japaneseFake) {
|
|
2411
|
+
return japaneseFake;
|
|
2412
|
+
}
|
|
2352
2413
|
switch (type) {
|
|
2353
2414
|
case "String":
|
|
2354
2415
|
return generateStringFake(propertyName, property);
|
|
@@ -2529,7 +2590,12 @@ function generateFactory(schema, schemas, options, stubContent) {
|
|
|
2529
2590
|
}
|
|
2530
2591
|
continue;
|
|
2531
2592
|
}
|
|
2532
|
-
const
|
|
2593
|
+
const compoundFakes = generateJapaneseCompoundFake(propName, prop, options);
|
|
2594
|
+
if (compoundFakes) {
|
|
2595
|
+
attributes.push(...compoundFakes);
|
|
2596
|
+
continue;
|
|
2597
|
+
}
|
|
2598
|
+
const fake = generateFakeData(propName, prop, schema, schemas, options);
|
|
2533
2599
|
if (fake) {
|
|
2534
2600
|
attributes.push(fake);
|
|
2535
2601
|
}
|
|
@@ -2699,6 +2765,33 @@ function generateStoreRules(propName, propDef, schema, schemas, options) {
|
|
|
2699
2765
|
}
|
|
2700
2766
|
}
|
|
2701
2767
|
break;
|
|
2768
|
+
default:
|
|
2769
|
+
const customType = options.customTypes.get(propDef.type);
|
|
2770
|
+
if (customType && !customType.compound) {
|
|
2771
|
+
if (propDef.type === "JapanesePhone") {
|
|
2772
|
+
rules.push("'string'");
|
|
2773
|
+
rules.push("'max:15'");
|
|
2774
|
+
rules.push("'regex:/^\\d{2,4}-\\d{2,4}-\\d{4}$/'");
|
|
2775
|
+
} else if (propDef.type === "JapanesePostalCode") {
|
|
2776
|
+
rules.push("'string'");
|
|
2777
|
+
rules.push("'max:8'");
|
|
2778
|
+
rules.push("'regex:/^\\d{3}-\\d{4}$/'");
|
|
2779
|
+
} else {
|
|
2780
|
+
const sqlType = customType.sql?.sqlType ?? "VARCHAR";
|
|
2781
|
+
const sqlLength = customType.sql?.length ?? 255;
|
|
2782
|
+
if (sqlType === "VARCHAR" || sqlType === "TEXT") {
|
|
2783
|
+
rules.push("'string'");
|
|
2784
|
+
if (sqlType === "VARCHAR") {
|
|
2785
|
+
rules.push(`'max:${sqlLength}'`);
|
|
2786
|
+
}
|
|
2787
|
+
} else if (sqlType === "INT" || sqlType === "TINYINT" || sqlType === "BIGINT") {
|
|
2788
|
+
rules.push("'integer'");
|
|
2789
|
+
} else if (sqlType === "DECIMAL" || sqlType === "FLOAT") {
|
|
2790
|
+
rules.push("'numeric'");
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
break;
|
|
2702
2795
|
}
|
|
2703
2796
|
if (prop.unique === true) {
|
|
2704
2797
|
rules.push(`'unique:${tableName}'`);
|
|
@@ -2781,12 +2874,100 @@ function generateUpdateRules(propName, propDef, schema, schemas, options) {
|
|
|
2781
2874
|
}
|
|
2782
2875
|
}
|
|
2783
2876
|
break;
|
|
2877
|
+
default:
|
|
2878
|
+
const customType = options.customTypes.get(propDef.type);
|
|
2879
|
+
if (customType && !customType.compound) {
|
|
2880
|
+
if (propDef.type === "JapanesePhone") {
|
|
2881
|
+
rules.push("'string'");
|
|
2882
|
+
rules.push("'max:15'");
|
|
2883
|
+
rules.push("'regex:/^\\d{2,4}-\\d{2,4}-\\d{4}$/'");
|
|
2884
|
+
} else if (propDef.type === "JapanesePostalCode") {
|
|
2885
|
+
rules.push("'string'");
|
|
2886
|
+
rules.push("'max:8'");
|
|
2887
|
+
rules.push("'regex:/^\\d{3}-\\d{4}$/'");
|
|
2888
|
+
} else {
|
|
2889
|
+
const sqlType = customType.sql?.sqlType ?? "VARCHAR";
|
|
2890
|
+
const sqlLength = customType.sql?.length ?? 255;
|
|
2891
|
+
if (sqlType === "VARCHAR" || sqlType === "TEXT") {
|
|
2892
|
+
rules.push("'string'");
|
|
2893
|
+
if (sqlType === "VARCHAR") {
|
|
2894
|
+
rules.push(`'max:${sqlLength}'`);
|
|
2895
|
+
}
|
|
2896
|
+
} else if (sqlType === "INT" || sqlType === "TINYINT" || sqlType === "BIGINT") {
|
|
2897
|
+
rules.push("'integer'");
|
|
2898
|
+
} else if (sqlType === "DECIMAL" || sqlType === "FLOAT") {
|
|
2899
|
+
rules.push("'numeric'");
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
break;
|
|
2784
2904
|
}
|
|
2785
2905
|
if (prop.unique === true) {
|
|
2786
2906
|
rules.push(`Rule::unique('${tableName}')->ignore($this->route('${modelVar}'))`);
|
|
2787
2907
|
}
|
|
2788
2908
|
return rules;
|
|
2789
2909
|
}
|
|
2910
|
+
function getCompoundFieldRules(typeName, suffix, field, fieldOverride) {
|
|
2911
|
+
const rules = [];
|
|
2912
|
+
const sql = field.sql;
|
|
2913
|
+
const length = fieldOverride?.length ?? sql?.length ?? 255;
|
|
2914
|
+
switch (typeName) {
|
|
2915
|
+
case "JapaneseName":
|
|
2916
|
+
rules.push("'string'");
|
|
2917
|
+
rules.push(`'max:${length}'`);
|
|
2918
|
+
if (suffix === "KanaLastname" || suffix === "KanaFirstname") {
|
|
2919
|
+
rules.push("'regex:/^[\\x{30A0}-\\x{30FF}\\x{3000}-\\x{303F}\\x{FF00}-\\x{FF9F}\\s]+$/u'");
|
|
2920
|
+
}
|
|
2921
|
+
break;
|
|
2922
|
+
case "JapaneseAddress":
|
|
2923
|
+
if (suffix === "PostalCode") {
|
|
2924
|
+
rules.push("'string'");
|
|
2925
|
+
rules.push("'max:8'");
|
|
2926
|
+
rules.push("'regex:/^\\d{3}-\\d{4}$/'");
|
|
2927
|
+
} else if (suffix === "PrefectureId") {
|
|
2928
|
+
rules.push("'integer'");
|
|
2929
|
+
rules.push("'between:1,47'");
|
|
2930
|
+
} else {
|
|
2931
|
+
rules.push("'string'");
|
|
2932
|
+
rules.push(`'max:${length}'`);
|
|
2933
|
+
}
|
|
2934
|
+
break;
|
|
2935
|
+
case "JapaneseBankAccount":
|
|
2936
|
+
if (suffix === "BankCode") {
|
|
2937
|
+
rules.push("'string'");
|
|
2938
|
+
rules.push("'size:4'");
|
|
2939
|
+
rules.push("'regex:/^\\d{4}$/'");
|
|
2940
|
+
} else if (suffix === "BranchCode") {
|
|
2941
|
+
rules.push("'string'");
|
|
2942
|
+
rules.push("'size:3'");
|
|
2943
|
+
rules.push("'regex:/^\\d{3}$/'");
|
|
2944
|
+
} else if (suffix === "AccountType") {
|
|
2945
|
+
rules.push("'string'");
|
|
2946
|
+
rules.push("Rule::in(['1', '2', '4'])");
|
|
2947
|
+
} else if (suffix === "AccountNumber") {
|
|
2948
|
+
rules.push("'string'");
|
|
2949
|
+
rules.push("'max:7'");
|
|
2950
|
+
rules.push("'regex:/^\\d{1,7}$/'");
|
|
2951
|
+
} else if (suffix === "AccountHolder") {
|
|
2952
|
+
rules.push("'string'");
|
|
2953
|
+
rules.push(`'max:${length}'`);
|
|
2954
|
+
rules.push("'regex:/^[\\x{30A0}-\\x{30FF}\\x{3000}-\\x{303F}\\x{FF00}-\\x{FF9F}\\s]+$/u'");
|
|
2955
|
+
}
|
|
2956
|
+
break;
|
|
2957
|
+
default:
|
|
2958
|
+
if (sql?.sqlType === "TINYINT" || sql?.sqlType === "INT" || sql?.sqlType === "BIGINT") {
|
|
2959
|
+
rules.push("'integer'");
|
|
2960
|
+
if (sql?.unsigned) {
|
|
2961
|
+
rules.push("'min:0'");
|
|
2962
|
+
}
|
|
2963
|
+
} else {
|
|
2964
|
+
rules.push("'string'");
|
|
2965
|
+
rules.push(`'max:${length}'`);
|
|
2966
|
+
}
|
|
2967
|
+
break;
|
|
2968
|
+
}
|
|
2969
|
+
return rules;
|
|
2970
|
+
}
|
|
2790
2971
|
function expandCompoundTypeFields(propName, propDef, options) {
|
|
2791
2972
|
const typeDef = options.customTypes.get(propDef.type);
|
|
2792
2973
|
if (!typeDef || !typeDef.compound || !typeDef.expand) {
|
|
@@ -2800,18 +2981,18 @@ function expandCompoundTypeFields(propName, propDef, options) {
|
|
|
2800
2981
|
const suffixSnake = toSnakeCase(field.suffix);
|
|
2801
2982
|
const fieldName = `${snakeName}_${suffixSnake}`;
|
|
2802
2983
|
const fieldOverride = prop.fields?.[field.suffix];
|
|
2803
|
-
const
|
|
2984
|
+
const fieldDefNullable = field.sql?.nullable ?? false;
|
|
2985
|
+
const fieldNullable = fieldOverride?.nullable ?? fieldDefNullable ?? isNullable2;
|
|
2804
2986
|
const rules = [];
|
|
2805
2987
|
if (!fieldNullable) {
|
|
2806
2988
|
rules.push("'required'");
|
|
2807
2989
|
} else {
|
|
2808
2990
|
rules.push("'nullable'");
|
|
2809
2991
|
}
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
const
|
|
2813
|
-
|
|
2814
|
-
fields.push({ fieldName, rules });
|
|
2992
|
+
const typeRules = getCompoundFieldRules(propDef.type, field.suffix, field, fieldOverride);
|
|
2993
|
+
rules.push(...typeRules);
|
|
2994
|
+
const needsRuleImport = rules.some((r) => r.includes("Rule::"));
|
|
2995
|
+
fields.push({ fieldName, rules, needsRuleImport });
|
|
2815
2996
|
}
|
|
2816
2997
|
return fields;
|
|
2817
2998
|
}
|
|
@@ -2845,6 +3026,7 @@ function generateStoreRequestBase(schema, schemas, options) {
|
|
|
2845
3026
|
const expandedFields = expandCompoundTypeFields(propName, propDef, options);
|
|
2846
3027
|
if (expandedFields.length > 0) {
|
|
2847
3028
|
for (const field of expandedFields) {
|
|
3029
|
+
if (field.needsRuleImport) needsRuleImport = true;
|
|
2848
3030
|
rulesLines.push(` '${field.fieldName}' => [${field.rules.join(", ")}],`);
|
|
2849
3031
|
fieldList.push(field.fieldName);
|
|
2850
3032
|
attributeLines.push(` '${field.fieldName}' => '${escapePhpString2(field.fieldName)}',`);
|
|
@@ -2941,6 +3123,7 @@ function generateUpdateRequestBase(schema, schemas, options) {
|
|
|
2941
3123
|
const expandedFields = expandCompoundTypeFields(propName, propDef, options);
|
|
2942
3124
|
if (expandedFields.length > 0) {
|
|
2943
3125
|
for (const field of expandedFields) {
|
|
3126
|
+
if (field.needsRuleImport) needsRuleImport = true;
|
|
2944
3127
|
const updateRules = field.rules.map((r) => r === "'required'" ? "'sometimes'" : r);
|
|
2945
3128
|
rulesLines.push(` '${field.fieldName}' => [${updateRules.join(", ")}],`);
|
|
2946
3129
|
attributeLines.push(` '${field.fieldName}' => '${escapePhpString2(field.fieldName)}',`);
|
|
@@ -2948,7 +3131,7 @@ function generateUpdateRequestBase(schema, schemas, options) {
|
|
|
2948
3131
|
continue;
|
|
2949
3132
|
}
|
|
2950
3133
|
const rules = generateUpdateRules(propName, propDef, schema, schemas, options);
|
|
2951
|
-
if (rules.some((r) => r.includes("Rule::")
|
|
3134
|
+
if (rules.some((r) => r.includes("Rule::"))) needsRuleImport = true;
|
|
2952
3135
|
rulesLines.push(` '${snakeName}' => [${rules.join(", ")}],`);
|
|
2953
3136
|
const displayName = getDisplayName(propDef.displayName, options.locale, propName);
|
|
2954
3137
|
attributeLines.push(` '${snakeName}' => '${escapePhpString2(displayName)}',`);
|
|
@@ -3174,6 +3357,230 @@ function getRequestPath(request) {
|
|
|
3174
3357
|
return request.path;
|
|
3175
3358
|
}
|
|
3176
3359
|
|
|
3360
|
+
// src/resource/generator.ts
|
|
3361
|
+
var import_omnify_types4 = require("@famgia/omnify-types");
|
|
3362
|
+
var DEFAULT_OPTIONS3 = {
|
|
3363
|
+
baseResourceNamespace: "App\\Http\\Resources\\OmnifyBase",
|
|
3364
|
+
resourceNamespace: "App\\Http\\Resources",
|
|
3365
|
+
baseResourcePath: "app/Http/Resources/OmnifyBase",
|
|
3366
|
+
resourcePath: "app/Http/Resources",
|
|
3367
|
+
customTypes: /* @__PURE__ */ new Map(),
|
|
3368
|
+
locale: "en"
|
|
3369
|
+
};
|
|
3370
|
+
var SKIP_FIELDS2 = /* @__PURE__ */ new Set([
|
|
3371
|
+
"password",
|
|
3372
|
+
"remember_token"
|
|
3373
|
+
]);
|
|
3374
|
+
function resolveOptions4(options) {
|
|
3375
|
+
return {
|
|
3376
|
+
baseResourceNamespace: options?.baseResourceNamespace ?? DEFAULT_OPTIONS3.baseResourceNamespace,
|
|
3377
|
+
resourceNamespace: options?.resourceNamespace ?? DEFAULT_OPTIONS3.resourceNamespace,
|
|
3378
|
+
baseResourcePath: options?.baseResourcePath ?? DEFAULT_OPTIONS3.baseResourcePath,
|
|
3379
|
+
resourcePath: options?.resourcePath ?? DEFAULT_OPTIONS3.resourcePath,
|
|
3380
|
+
customTypes: options?.customTypes ?? /* @__PURE__ */ new Map(),
|
|
3381
|
+
locale: options?.locale ?? DEFAULT_OPTIONS3.locale
|
|
3382
|
+
};
|
|
3383
|
+
}
|
|
3384
|
+
function getModuleName2(schema) {
|
|
3385
|
+
if (schema.module) {
|
|
3386
|
+
return schema.module;
|
|
3387
|
+
}
|
|
3388
|
+
return "";
|
|
3389
|
+
}
|
|
3390
|
+
function getPropertyOutput(propName, propDef, schemas, options) {
|
|
3391
|
+
const snakeName = toSnakeCase(propName);
|
|
3392
|
+
const lines = [];
|
|
3393
|
+
if (SKIP_FIELDS2.has(snakeName)) {
|
|
3394
|
+
return lines;
|
|
3395
|
+
}
|
|
3396
|
+
if (propDef.type === "Association") {
|
|
3397
|
+
const assoc = propDef;
|
|
3398
|
+
const targetClass = assoc.target ? toPascalCase(assoc.target) : "";
|
|
3399
|
+
switch (assoc.relation) {
|
|
3400
|
+
case "ManyToOne":
|
|
3401
|
+
case "OneToOne":
|
|
3402
|
+
lines.push(` '${snakeName}_id' => $this->${snakeName}_id,`);
|
|
3403
|
+
lines.push(` '${snakeName}' => $this->whenLoaded('${toCamelCase(propName)}', fn() => new ${targetClass}Resource($this->${toCamelCase(propName)})),`);
|
|
3404
|
+
break;
|
|
3405
|
+
case "OneToMany":
|
|
3406
|
+
case "ManyToMany":
|
|
3407
|
+
lines.push(` '${snakeName}' => $this->whenLoaded('${toCamelCase(propName)}', fn() => ${targetClass}Resource::collection($this->${toCamelCase(propName)})),`);
|
|
3408
|
+
break;
|
|
3409
|
+
case "MorphTo":
|
|
3410
|
+
lines.push(` '${snakeName}_type' => $this->${snakeName}_type,`);
|
|
3411
|
+
lines.push(` '${snakeName}_id' => $this->${snakeName}_id,`);
|
|
3412
|
+
lines.push(` '${snakeName}' => $this->whenLoaded('${toCamelCase(propName)}'),`);
|
|
3413
|
+
break;
|
|
3414
|
+
case "MorphOne":
|
|
3415
|
+
case "MorphMany":
|
|
3416
|
+
lines.push(` '${snakeName}' => $this->whenLoaded('${toCamelCase(propName)}', fn() => ${targetClass}Resource::collection($this->${toCamelCase(propName)})),`);
|
|
3417
|
+
break;
|
|
3418
|
+
}
|
|
3419
|
+
return lines;
|
|
3420
|
+
}
|
|
3421
|
+
const typeDef = options.customTypes.get(propDef.type);
|
|
3422
|
+
if (typeDef?.compound && typeDef.expand) {
|
|
3423
|
+
for (const field of typeDef.expand) {
|
|
3424
|
+
const suffixSnake = toSnakeCase(field.suffix);
|
|
3425
|
+
const fieldName = `${snakeName}_${suffixSnake}`;
|
|
3426
|
+
lines.push(` '${fieldName}' => $this->${fieldName},`);
|
|
3427
|
+
}
|
|
3428
|
+
if (typeDef.accessors) {
|
|
3429
|
+
for (const accessor of typeDef.accessors) {
|
|
3430
|
+
const accessorName = `${snakeName}_${toSnakeCase(accessor.name)}`;
|
|
3431
|
+
lines.push(` '${accessorName}' => $this->${accessorName},`);
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
return lines;
|
|
3435
|
+
}
|
|
3436
|
+
lines.push(` '${snakeName}' => $this->${snakeName},`);
|
|
3437
|
+
return lines;
|
|
3438
|
+
}
|
|
3439
|
+
function generateResourceBase(schema, schemas, options) {
|
|
3440
|
+
const className = toPascalCase(schema.name);
|
|
3441
|
+
const module2 = getModuleName2(schema);
|
|
3442
|
+
const namespaceModule = module2 ? `\\${module2}` : "";
|
|
3443
|
+
const namespace = `${options.baseResourceNamespace}${namespaceModule}`;
|
|
3444
|
+
const properties = schema.properties ?? {};
|
|
3445
|
+
const outputLines = [];
|
|
3446
|
+
const imports = /* @__PURE__ */ new Set();
|
|
3447
|
+
if (schema.options?.id !== false) {
|
|
3448
|
+
outputLines.push(` 'id' => $this->id,`);
|
|
3449
|
+
}
|
|
3450
|
+
for (const [propName, propDef] of Object.entries(properties)) {
|
|
3451
|
+
const lines = getPropertyOutput(propName, propDef, schemas, options);
|
|
3452
|
+
outputLines.push(...lines);
|
|
3453
|
+
if (propDef.type === "Association") {
|
|
3454
|
+
const assoc = propDef;
|
|
3455
|
+
if (assoc.target) {
|
|
3456
|
+
const targetModule = getModuleName2(schemas[assoc.target] ?? schema);
|
|
3457
|
+
const targetModuleNs = targetModule ? `\\${targetModule}` : "";
|
|
3458
|
+
imports.add(`use ${options.resourceNamespace}${targetModuleNs}\\${toPascalCase(assoc.target)}Resource;`);
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
if (schema.options?.timestamps !== false) {
|
|
3463
|
+
outputLines.push(` 'created_at' => $this->created_at?->toISOString(),`);
|
|
3464
|
+
outputLines.push(` 'updated_at' => $this->updated_at?->toISOString(),`);
|
|
3465
|
+
}
|
|
3466
|
+
if (schema.options?.softDelete) {
|
|
3467
|
+
outputLines.push(` 'deleted_at' => $this->deleted_at?->toISOString(),`);
|
|
3468
|
+
}
|
|
3469
|
+
const importLines = Array.from(imports).sort().join("\n");
|
|
3470
|
+
const importBlock = importLines ? `
|
|
3471
|
+
${importLines}` : "";
|
|
3472
|
+
const content = `<?php
|
|
3473
|
+
|
|
3474
|
+
/**
|
|
3475
|
+
* AUTO-GENERATED BY OMNIFY - DO NOT EDIT!
|
|
3476
|
+
*
|
|
3477
|
+
* This file is generated from Omnify schema: ${schema.name}
|
|
3478
|
+
* Re-run \`npx omnify generate\` to update.
|
|
3479
|
+
*
|
|
3480
|
+
* @generated
|
|
3481
|
+
*/
|
|
3482
|
+
|
|
3483
|
+
namespace ${namespace};
|
|
3484
|
+
|
|
3485
|
+
use Illuminate\\Http\\Request;
|
|
3486
|
+
use Illuminate\\Http\\Resources\\Json\\JsonResource;${importBlock}
|
|
3487
|
+
|
|
3488
|
+
class ${className}ResourceBase extends JsonResource
|
|
3489
|
+
{
|
|
3490
|
+
/**
|
|
3491
|
+
* Transform the resource into an array.
|
|
3492
|
+
*
|
|
3493
|
+
* @return array<string, mixed>
|
|
3494
|
+
*/
|
|
3495
|
+
protected function schemaArray(Request $request): array
|
|
3496
|
+
{
|
|
3497
|
+
return [
|
|
3498
|
+
${outputLines.join("\n")}
|
|
3499
|
+
];
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
`;
|
|
3503
|
+
const modulePath = module2 ? `/${module2}` : "";
|
|
3504
|
+
return {
|
|
3505
|
+
path: `${options.baseResourcePath}${modulePath}/${className}ResourceBase.php`,
|
|
3506
|
+
content,
|
|
3507
|
+
type: "base",
|
|
3508
|
+
overwrite: true,
|
|
3509
|
+
schemaName: schema.name,
|
|
3510
|
+
module: module2
|
|
3511
|
+
};
|
|
3512
|
+
}
|
|
3513
|
+
function generateResource(schema, options) {
|
|
3514
|
+
const className = toPascalCase(schema.name);
|
|
3515
|
+
const module2 = getModuleName2(schema);
|
|
3516
|
+
const namespaceModule = module2 ? `\\${module2}` : "";
|
|
3517
|
+
const namespace = `${options.resourceNamespace}${namespaceModule}`;
|
|
3518
|
+
const baseNamespace = `${options.baseResourceNamespace}${namespaceModule}`;
|
|
3519
|
+
const content = `<?php
|
|
3520
|
+
|
|
3521
|
+
/**
|
|
3522
|
+
* ${className} Resource
|
|
3523
|
+
*
|
|
3524
|
+
* SAFE TO EDIT - This file is never overwritten by Omnify.
|
|
3525
|
+
*/
|
|
3526
|
+
|
|
3527
|
+
namespace ${namespace};
|
|
3528
|
+
|
|
3529
|
+
use Illuminate\\Http\\Request;
|
|
3530
|
+
use ${baseNamespace}\\${className}ResourceBase;
|
|
3531
|
+
|
|
3532
|
+
class ${className}Resource extends ${className}ResourceBase
|
|
3533
|
+
{
|
|
3534
|
+
/**
|
|
3535
|
+
* Transform the resource into an array.
|
|
3536
|
+
*
|
|
3537
|
+
* @return array<string, mixed>
|
|
3538
|
+
*/
|
|
3539
|
+
public function toArray(Request $request): array
|
|
3540
|
+
{
|
|
3541
|
+
return array_merge($this->schemaArray($request), [
|
|
3542
|
+
// Custom fields here
|
|
3543
|
+
]);
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3546
|
+
/**
|
|
3547
|
+
* Get additional data that should be returned with the resource array.
|
|
3548
|
+
*
|
|
3549
|
+
* @return array<string, mixed>
|
|
3550
|
+
*/
|
|
3551
|
+
public function with(Request $request): array
|
|
3552
|
+
{
|
|
3553
|
+
return [
|
|
3554
|
+
// Additional metadata here
|
|
3555
|
+
];
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3558
|
+
`;
|
|
3559
|
+
const modulePath = module2 ? `/${module2}` : "";
|
|
3560
|
+
return {
|
|
3561
|
+
path: `${options.resourcePath}${modulePath}/${className}Resource.php`,
|
|
3562
|
+
content,
|
|
3563
|
+
type: "user",
|
|
3564
|
+
overwrite: false,
|
|
3565
|
+
schemaName: schema.name,
|
|
3566
|
+
module: module2
|
|
3567
|
+
};
|
|
3568
|
+
}
|
|
3569
|
+
function generateResources(schemas, options) {
|
|
3570
|
+
const resolved = resolveOptions4(options);
|
|
3571
|
+
const resources = [];
|
|
3572
|
+
for (const schema of Object.values(schemas)) {
|
|
3573
|
+
if (schema.kind === "enum") continue;
|
|
3574
|
+
if (schema.options?.hidden === true) continue;
|
|
3575
|
+
resources.push(generateResourceBase(schema, schemas, resolved));
|
|
3576
|
+
resources.push(generateResource(schema, resolved));
|
|
3577
|
+
}
|
|
3578
|
+
return resources;
|
|
3579
|
+
}
|
|
3580
|
+
function getResourcePath(resource) {
|
|
3581
|
+
return resource.path;
|
|
3582
|
+
}
|
|
3583
|
+
|
|
3177
3584
|
// src/plugin.ts
|
|
3178
3585
|
function getExistingMigrationTables(migrationsDir) {
|
|
3179
3586
|
const existingTables = /* @__PURE__ */ new Set();
|
|
@@ -3282,10 +3689,34 @@ var LARAVEL_CONFIG_SCHEMA = {
|
|
|
3282
3689
|
description: "Generate Laravel FormRequest classes for validation",
|
|
3283
3690
|
default: false,
|
|
3284
3691
|
group: "options"
|
|
3692
|
+
},
|
|
3693
|
+
{
|
|
3694
|
+
key: "resourcesPath",
|
|
3695
|
+
type: "path",
|
|
3696
|
+
label: "Resources Path",
|
|
3697
|
+
description: "Directory for user-editable API Resource files",
|
|
3698
|
+
default: "app/Http/Resources",
|
|
3699
|
+
group: "output"
|
|
3700
|
+
},
|
|
3701
|
+
{
|
|
3702
|
+
key: "baseResourcesPath",
|
|
3703
|
+
type: "path",
|
|
3704
|
+
label: "Base Resources Path",
|
|
3705
|
+
description: "Directory for auto-generated base API Resource files",
|
|
3706
|
+
default: "app/Http/Resources/OmnifyBase",
|
|
3707
|
+
group: "output"
|
|
3708
|
+
},
|
|
3709
|
+
{
|
|
3710
|
+
key: "generateResources",
|
|
3711
|
+
type: "boolean",
|
|
3712
|
+
label: "Generate Resources",
|
|
3713
|
+
description: "Generate Laravel API Resource classes",
|
|
3714
|
+
default: false,
|
|
3715
|
+
group: "options"
|
|
3285
3716
|
}
|
|
3286
3717
|
]
|
|
3287
3718
|
};
|
|
3288
|
-
function
|
|
3719
|
+
function resolveOptions5(options) {
|
|
3289
3720
|
return {
|
|
3290
3721
|
migrationsPath: options?.migrationsPath ?? "database/migrations/omnify",
|
|
3291
3722
|
modelsPath: options?.modelsPath ?? "app/Models",
|
|
@@ -3303,11 +3734,16 @@ function resolveOptions4(options) {
|
|
|
3303
3734
|
baseRequestsPath: options?.baseRequestsPath ?? "app/Http/Requests/OmnifyBase",
|
|
3304
3735
|
requestNamespace: options?.requestNamespace ?? "App\\Http\\Requests",
|
|
3305
3736
|
baseRequestNamespace: options?.baseRequestNamespace ?? "App\\Http\\Requests\\OmnifyBase",
|
|
3306
|
-
generateRequests: options?.generateRequests ?? false
|
|
3737
|
+
generateRequests: options?.generateRequests ?? false,
|
|
3738
|
+
resourcesPath: options?.resourcesPath ?? "app/Http/Resources",
|
|
3739
|
+
baseResourcesPath: options?.baseResourcesPath ?? "app/Http/Resources/OmnifyBase",
|
|
3740
|
+
resourceNamespace: options?.resourceNamespace ?? "App\\Http\\Resources",
|
|
3741
|
+
baseResourceNamespace: options?.baseResourceNamespace ?? "App\\Http\\Resources\\OmnifyBase",
|
|
3742
|
+
generateResources: options?.generateResources ?? false
|
|
3307
3743
|
};
|
|
3308
3744
|
}
|
|
3309
3745
|
function laravelPlugin(options) {
|
|
3310
|
-
const resolved =
|
|
3746
|
+
const resolved = resolveOptions5(options);
|
|
3311
3747
|
const migrationGenerator = {
|
|
3312
3748
|
name: "laravel-migrations",
|
|
3313
3749
|
description: "Generate Laravel migration files",
|
|
@@ -3463,7 +3899,8 @@ function laravelPlugin(options) {
|
|
|
3463
3899
|
const factoryOptions = {
|
|
3464
3900
|
modelNamespace: resolved.modelNamespace,
|
|
3465
3901
|
factoryPath: resolved.factoriesPath,
|
|
3466
|
-
fakerLocale: resolved.fakerLocale
|
|
3902
|
+
fakerLocale: resolved.fakerLocale,
|
|
3903
|
+
customTypes: ctx.customTypes
|
|
3467
3904
|
};
|
|
3468
3905
|
const factories = generateFactories(ctx.schemas, factoryOptions);
|
|
3469
3906
|
return factories.map((factory) => ({
|
|
@@ -3506,6 +3943,32 @@ function laravelPlugin(options) {
|
|
|
3506
3943
|
}));
|
|
3507
3944
|
}
|
|
3508
3945
|
};
|
|
3946
|
+
const resourceGenerator = {
|
|
3947
|
+
name: "laravel-resources",
|
|
3948
|
+
description: "Generate Laravel API Resource classes",
|
|
3949
|
+
generate: async (ctx) => {
|
|
3950
|
+
const resourceOptions = {
|
|
3951
|
+
resourceNamespace: resolved.resourceNamespace,
|
|
3952
|
+
baseResourceNamespace: resolved.baseResourceNamespace,
|
|
3953
|
+
resourcePath: resolved.resourcesPath,
|
|
3954
|
+
baseResourcePath: resolved.baseResourcesPath,
|
|
3955
|
+
customTypes: ctx.customTypes
|
|
3956
|
+
};
|
|
3957
|
+
const resources = generateResources(ctx.schemas, resourceOptions);
|
|
3958
|
+
return resources.map((resource) => ({
|
|
3959
|
+
path: getResourcePath(resource),
|
|
3960
|
+
content: resource.content,
|
|
3961
|
+
type: "other",
|
|
3962
|
+
// Skip writing user resources if they already exist
|
|
3963
|
+
skipIfExists: !resource.overwrite,
|
|
3964
|
+
metadata: {
|
|
3965
|
+
resourceType: resource.type,
|
|
3966
|
+
schemaName: resource.schemaName,
|
|
3967
|
+
module: resource.module
|
|
3968
|
+
}
|
|
3969
|
+
}));
|
|
3970
|
+
}
|
|
3971
|
+
};
|
|
3509
3972
|
const generators = [migrationGenerator];
|
|
3510
3973
|
if (resolved.generateModels) {
|
|
3511
3974
|
generators.push(modelGenerator);
|
|
@@ -3516,6 +3979,9 @@ function laravelPlugin(options) {
|
|
|
3516
3979
|
if (resolved.generateRequests) {
|
|
3517
3980
|
generators.push(requestGenerator);
|
|
3518
3981
|
}
|
|
3982
|
+
if (resolved.generateResources) {
|
|
3983
|
+
generators.push(resourceGenerator);
|
|
3984
|
+
}
|
|
3519
3985
|
return {
|
|
3520
3986
|
name: "@famgia/omnify-laravel",
|
|
3521
3987
|
version: "0.0.14",
|