routesync 1.0.15 → 1.0.16
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/README.md +14 -0
- package/dist/cli.js +36 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -249,6 +249,20 @@ const api = defineApi({
|
|
|
249
249
|
}, config)
|
|
250
250
|
```
|
|
251
251
|
|
|
252
|
+
> **Note on Laravel Auto-generation:** When using `routesync sync` or `routesync scan` with the `--zod` flag, RouteSync uses PHP Reflection to automatically generate Zod schemas based on your backend validation rules.
|
|
253
|
+
>
|
|
254
|
+
> **Important:** To ensure your schemas are detected automatically, you **must use Laravel `FormRequest` classes**. Inline `$request->validate([...])` calls inside Controller methods cannot be reliably extracted.
|
|
255
|
+
>
|
|
256
|
+
> ```php
|
|
257
|
+
> // ✅ DO THIS: RouteSync will generate Zod schemas automatically
|
|
258
|
+
> public function store(StoreProductRequest $request)
|
|
259
|
+
>
|
|
260
|
+
> // ❌ AVOID THIS: Validation rules will be ignored
|
|
261
|
+
> public function store(Request $request) {
|
|
262
|
+
> $request->validate([...]);
|
|
263
|
+
> }
|
|
264
|
+
> ```
|
|
265
|
+
|
|
252
266
|
---
|
|
253
267
|
|
|
254
268
|
### Auto-generate TanStack hooks from defineApi
|
package/dist/cli.js
CHANGED
|
@@ -8406,6 +8406,31 @@ foreach ($routes as $route) {
|
|
|
8406
8406
|
}
|
|
8407
8407
|
}
|
|
8408
8408
|
}
|
|
8409
|
+
|
|
8410
|
+
// Fallback: Try to parse $request->validate([...]) from source code
|
|
8411
|
+
if (empty($schema)) {
|
|
8412
|
+
$fileName = $reflector->getFileName();
|
|
8413
|
+
$startLine = $reflector->getStartLine();
|
|
8414
|
+
$endLine = $reflector->getEndLine();
|
|
8415
|
+
|
|
8416
|
+
if ($fileName && $startLine !== false && $endLine !== false) {
|
|
8417
|
+
$lines = file($fileName);
|
|
8418
|
+
// startLine is 1-indexed
|
|
8419
|
+
$methodSource = implode("", array_slice($lines, $startLine - 1, $endLine - $startLine + 1));
|
|
8420
|
+
|
|
8421
|
+
// Look for $request->validate([ ... ])
|
|
8422
|
+
if (preg_match('/\\\\$request->validate\\\\s*\\\\(\\\\s*\\\\[(.*?)\\\\]\\\\s*\\\\)/s', $methodSource, $matches)) {
|
|
8423
|
+
$rulesString = $matches[1];
|
|
8424
|
+
// Match 'field' => 'rules'
|
|
8425
|
+
preg_match_all('~[\\'"]([a-zA-Z0-9_.*]+)[\\'"]\\\\s*=>\\\\s*[\\'"](.*?)[\\'"]~', $rulesString, $ruleMatches);
|
|
8426
|
+
if (!empty($ruleMatches[1])) {
|
|
8427
|
+
foreach ($ruleMatches[1] as $index => $field) {
|
|
8428
|
+
$schema[$field] = $ruleMatches[2][$index];
|
|
8429
|
+
}
|
|
8430
|
+
}
|
|
8431
|
+
}
|
|
8432
|
+
}
|
|
8433
|
+
}
|
|
8409
8434
|
} catch (\\Exception $e) {}
|
|
8410
8435
|
}
|
|
8411
8436
|
}
|
|
@@ -8751,6 +8776,11 @@ var TypeGenerator = class {
|
|
|
8751
8776
|
const isOptional = col.nullable ? "?" : "";
|
|
8752
8777
|
lines.push(` ${col.name}${isOptional}: ${tsType}`);
|
|
8753
8778
|
}
|
|
8779
|
+
if (model.appends && model.appends.length > 0) {
|
|
8780
|
+
for (const append of model.appends) {
|
|
8781
|
+
lines.push(` ${append}?: unknown`);
|
|
8782
|
+
}
|
|
8783
|
+
}
|
|
8754
8784
|
lines.push(`}`);
|
|
8755
8785
|
lines.push(``);
|
|
8756
8786
|
}
|
|
@@ -8771,16 +8801,16 @@ var TypeGenerator = class {
|
|
|
8771
8801
|
}
|
|
8772
8802
|
if (hasSchemas) {
|
|
8773
8803
|
for (const route of manifest.routes) {
|
|
8774
|
-
if (route.schema && Object.keys(route.schema).length > 0) {
|
|
8804
|
+
if (route.schema && route.schema.rules && Object.keys(route.schema.rules).length > 0) {
|
|
8775
8805
|
const actionName = toMethodName(route);
|
|
8776
8806
|
const schemaName = actionName + "Schema";
|
|
8777
8807
|
lines.push(`export const ${schemaName} = z.object({`);
|
|
8778
|
-
for (const [field, rules] of Object.entries(route.schema)) {
|
|
8808
|
+
for (const [field, rules] of Object.entries(route.schema.rules)) {
|
|
8779
8809
|
const ruleStr = Array.isArray(rules) ? rules.join("|") : String(rules);
|
|
8780
8810
|
let zodRule = "z.string()";
|
|
8781
|
-
if (ruleStr.includes("numeric") || ruleStr.includes("integer")) {
|
|
8811
|
+
if (ruleStr.includes("numeric") || ruleStr.includes("integer") || ruleStr.includes("int")) {
|
|
8782
8812
|
zodRule = "z.number()";
|
|
8783
|
-
} else if (ruleStr.includes("boolean")) {
|
|
8813
|
+
} else if (ruleStr.includes("boolean") || ruleStr.includes("bool")) {
|
|
8784
8814
|
zodRule = "z.boolean()";
|
|
8785
8815
|
} else if (ruleStr.includes("array")) {
|
|
8786
8816
|
zodRule = "z.array(z.unknown())";
|
|
@@ -9100,7 +9130,7 @@ var ModelGenerator = class {
|
|
|
9100
9130
|
};
|
|
9101
9131
|
|
|
9102
9132
|
// packages/cli/src/commands/generate.ts
|
|
9103
|
-
var generateCommand = new Command("generate").description("Generate typed SDK, types, and hooks from route manifest").option("-m, --manifest <path>", "Path to route manifest", "routesync.manifest.json").option("-o, --output <path>", "Output directory", "src/api").option("--no-hooks", "Skip generating React hooks").option("--next-actions", "Generate Next.js Server Actions").option("--msw", "Generate MSW Mock Handlers").option("--echo", "Generate Laravel Echo Hooks").action(async (options) => {
|
|
9133
|
+
var generateCommand = new Command("generate").description("Generate typed SDK, types, and hooks from route manifest").option("-m, --manifest <path>", "Path to route manifest", "routesync.manifest.json").option("-o, --output <path>", "Output directory", "src/api").option("--no-hooks", "Skip generating React hooks").option("--next-actions", "Generate Next.js Server Actions").option("--msw", "Generate MSW Mock Handlers").option("--echo", "Generate Laravel Echo Hooks").option("--zod", "Generate Zod schemas for validation").action(async (options) => {
|
|
9104
9134
|
const spinner = ora("Generating SDK...").start();
|
|
9105
9135
|
try {
|
|
9106
9136
|
if (!import_fs_extra11.default.existsSync(options.manifest)) {
|
|
@@ -9113,7 +9143,7 @@ var generateCommand = new Command("generate").description("Generate typed SDK, t
|
|
|
9113
9143
|
spinner.text = "Generating types...";
|
|
9114
9144
|
await TypeGenerator.generate(manifest, options.output);
|
|
9115
9145
|
spinner.text = "Generating SDK...";
|
|
9116
|
-
await SDKGenerator.generate(manifest, options.output);
|
|
9146
|
+
await SDKGenerator.generate(manifest, options.output, options);
|
|
9117
9147
|
if (options.hooks !== false) {
|
|
9118
9148
|
spinner.text = "Generating hooks...";
|
|
9119
9149
|
await HookGenerator.generate(manifest, options.output);
|