routesync 1.0.41 → 1.0.43

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.
Files changed (2) hide show
  1. package/dist/cli.js +130 -219
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -8363,180 +8363,18 @@ var LaravelRouteParser = class {
8363
8363
  const projectRoot = import_path.default.resolve(import_path.default.dirname(filePath), "..");
8364
8364
  const extractModels = options.extractModels ? "true" : "false";
8365
8365
  const phpScript = `<?php
8366
+ error_reporting(0);
8366
8367
  require __DIR__.'/vendor/autoload.php';
8367
8368
  $app = require_once __DIR__.'/bootstrap/app.php';
8368
- $kernel = $app->make(IlluminateContractsConsoleKernel::class);
8369
+ $kernel = $app->make(Illuminate\\Contracts\\Console\\Kernel::class);
8369
8370
  $kernel->bootstrap();
8370
8371
 
8371
- $result = ['routes' => [], 'models' => []];
8372
-
8373
- // \u2500\u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
8374
-
8375
- function rsync_get_source(ReflectionFunctionAbstract $ref): ?string {
8376
- $file = $ref->getFileName();
8377
- $start = $ref->getStartLine();
8378
- $end = $ref->getEndLine();
8379
- if (!$file || $start === false || $end === false) return null;
8380
- return implode('', array_slice(file($file), $start - 1, $end - $start + 1));
8381
- }
8382
-
8383
- /**
8384
- * Try to resolve responseMetadata from a Resource class.
8385
- * Checks (in order):
8386
- * 1. PHP 8 #[RouteSyncResponse] attribute on class
8387
- * 2. @mixin docblock
8388
- * 3. Constructor parameter type hint \u2190 NEW
8389
- * 4. $this->resource @var docblock \u2190 NEW
8390
- * 5. Strip Resource suffix \u2192 match AppModels*
8391
- * 6. toArray() field vs DB column intersection
8392
- */
8393
- function rsync_infer_from_resource(string $resourceClass, bool $collection): ?array {
8394
- if (!class_exists($resourceClass)) return null;
8395
- $resRef = new ReflectionClass($resourceClass);
8396
-
8397
- // 1. PHP 8 attribute
8398
- foreach ($resRef->getAttributes() as $attr) {
8399
- $short = class_basename($attr->getName());
8400
- if (in_array($short, ['Response', 'RouteSyncResponse'])) {
8401
- $args = $attr->getArguments();
8402
- $type = $args[0] ?? $args['type'] ?? $args['model'] ?? $args['response'] ?? null;
8403
- if ($type) return ['type' => class_basename($type), 'collection' => $collection];
8404
- }
8405
- }
8406
-
8407
- // 2. @mixin docblock
8408
- $doc = $resRef->getDocComment();
8409
- if ($doc && preg_match('/@mixins+([\\\\w]+)/', $doc, $m)) {
8410
- return ['type' => class_basename($m[1]), 'collection' => $collection];
8411
- }
8412
-
8413
- // 3. Constructor parameter type hint: __construct(User $user)
8414
- if ($resRef->hasMethod('__construct')) {
8415
- $ctor = $resRef->getMethod('__construct');
8416
- foreach ($ctor->getParameters() as $param) {
8417
- $ptype = $param->getType();
8418
- if ($ptype && !$ptype->isBuiltin()) {
8419
- $cn = $ptype->getName();
8420
- if (is_subclass_of($cn, 'IlluminateDatabaseEloquentModel')) {
8421
- return ['type' => class_basename($cn), 'collection' => $collection];
8422
- }
8423
- }
8424
- }
8425
- }
8426
-
8427
- // 4. $this->resource @var docblock in class body or toArray()
8428
- $classDoc = $resRef->getDocComment() ?: '';
8429
- foreach (['toArray', 'toResponse'] as $mname) {
8430
- if ($resRef->hasMethod($mname)) {
8431
- $src = rsync_get_source($resRef->getMethod($mname)) ?? '';
8432
- $classDoc .= $src;
8433
- }
8434
- }
8435
- if (preg_match('/@vars+([\\\\w]+)s+$(?:resource|model)/', $classDoc, $m)) {
8436
- $cn = ltrim($m[1], '\\');
8437
- $fqcn = str_contains($cn, '\\') ? $cn : 'App\\Models\\' . $cn;
8438
- if (class_exists($fqcn)) {
8439
- return ['type' => class_basename($fqcn), 'collection' => $collection];
8440
- }
8441
- }
8442
-
8443
- // 5. Strip Resource suffix \u2192 AppModels<Name>
8444
- $inferredName = preg_replace('/Resource$/', '', class_basename($resourceClass));
8445
- if ($inferredName) {
8446
- $mc = 'App\\Models\\' . $inferredName;
8447
- if (class_exists($mc)) {
8448
- return ['type' => $inferredName, 'collection' => $collection];
8449
- }
8450
- }
8451
-
8452
- // 6. toArray() field vs DB column intersection
8453
- if ($resRef->hasMethod('toArray')) {
8454
- $src = rsync_get_source($resRef->getMethod('toArray')) ?? '';
8455
- preg_match_all('/['"]([a-zA-Z0-9_]+)['"]s*=>/', $src, $km);
8456
- $resFields = array_unique($km[1] ?? []);
8457
- if (!empty($resFields)) {
8458
- $bestModel = null; $bestScore = 0;
8459
- $modelsPath = app_path('Models');
8460
- if (is_dir($modelsPath)) {
8461
- foreach (IlluminateSupportFacadesFile::allFiles($modelsPath) as $mf) {
8462
- $mn = preg_replace('/.php$/', '', $mf->getFilename());
8463
- $mc = 'App\\Models\\' . $mn;
8464
- if (!class_exists($mc)) continue;
8465
- try {
8466
- $mi = new $mc();
8467
- $cols = array_column(IlluminateSupportFacadesSchema::getColumns($mi->getTable()), 'name');
8468
- $score = count(array_intersect($resFields, $cols));
8469
- if ($score > $bestScore) { $bestScore = $score; $bestModel = $mn; }
8470
- } catch (Exception $e) {}
8471
- }
8472
- }
8473
- if ($bestModel && $bestScore > 0) {
8474
- return ['type' => $bestModel, 'collection' => $collection];
8475
- }
8476
- }
8477
- }
8478
-
8479
- return null;
8480
- }
8481
-
8482
- /**
8483
- * Try to resolve responseMetadata directly from controller method source.
8484
- * Handles cases where no Resource class is used at all.
8485
- */
8486
- function rsync_infer_from_source(?string $source): ?array {
8487
- if (!$source) return null;
8488
-
8489
- // return new SomeResource($x)
8490
- if (preg_match('/returns+news+([a-zA-Z0-9_]+Resource)s*(/', $source, $m)) {
8491
- $rc = 'App\\Http\\Resources\\' . $m[1];
8492
- $result = rsync_infer_from_resource($rc, false);
8493
- if ($result) return $result;
8494
- }
8495
-
8496
- // SomeResource::collection(...)
8497
- if (preg_match('/([a-zA-Z0-9_]+Resource)::collections*(/', $source, $m)) {
8498
- $rc = 'App\\Http\\Resources\\' . $m[1];
8499
- $result = rsync_infer_from_resource($rc, true);
8500
- if ($result) return $result;
8501
- }
8502
-
8503
- // ->paginate() or ->simplePaginate() with Resource
8504
- if (preg_match('/([a-zA-Z0-9_]+Resource)::collection.*paginate/s', $source, $m)) {
8505
- $rc = 'App\\Http\\Resources\\' . $m[1];
8506
- $result = rsync_infer_from_resource($rc, true);
8507
- if ($result) { $result['paginated'] = true; return $result; }
8508
- }
8509
-
8510
- // response()->json(['token' => ..., 'user' => ...]) \u2014 inline array
8511
- // Extract top-level keys and try to match a model
8512
- if (preg_match('/response()s*->s*jsons*(s*[([^]]{0,800})]/', $source, $jsonMatch)) {
8513
- preg_match_all('/['"]([a-zA-Z0-9_]+)['"]s*=>/', $jsonMatch[1], $km);
8514
- $keys = array_unique($km[1] ?? []);
8515
- if (!empty($keys)) {
8516
- $bestModel = null; $bestScore = 0;
8517
- foreach (IlluminateSupportFacadesFile::allFiles(app_path('Models')) as $mf) {
8518
- $mn = preg_replace('/.php$/', '', $mf->getFilename());
8519
- $mc = 'App\\Models\\' . $mn;
8520
- if (!class_exists($mc)) continue;
8521
- try {
8522
- $mi = new $mc();
8523
- $cols = array_column(IlluminateSupportFacadesSchema::getColumns($mi->getTable()), 'name');
8524
- $camelCols = array_map(fn($c) => lcfirst(str_replace('_', '', ucwords($c, '_'))), $cols);
8525
- $score = count(array_intersect($keys, array_merge($cols, $camelCols)));
8526
- if ($score > $bestScore) { $bestScore = $score; $bestModel = $mn; }
8527
- } catch (Exception $e) {}
8528
- }
8529
- if ($bestModel && $bestScore >= 2) {
8530
- return ['type' => $bestModel, 'collection' => false];
8531
- }
8532
- }
8533
- }
8534
-
8535
- return null;
8536
- }
8537
-
8538
- // \u2500\u2500\u2500 Main Route Loop \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
8372
+ $result = [
8373
+ 'routes' => [],
8374
+ 'models' => []
8375
+ ];
8539
8376
 
8377
+ // Extract Routes
8540
8378
  $routes = app('router')->getRoutes();
8541
8379
  foreach ($routes as $route) {
8542
8380
  if (!str_starts_with($route->uri(), 'api/')) continue;
@@ -8552,21 +8390,17 @@ foreach ($routes as $route) {
8552
8390
  }
8553
8391
 
8554
8392
  $schema = [];
8555
- $responseMetadata = null;
8556
8393
  $action = $route->getAction();
8557
-
8558
8394
  if (isset($action['uses']) && is_string($action['uses']) && str_contains($action['uses'], '@')) {
8559
8395
  list($controller, $method) = explode('@', $action['uses']);
8560
8396
  if (class_exists($controller)) {
8561
8397
  try {
8562
8398
  $reflector = new ReflectionMethod($controller, $method);
8563
-
8564
- // \u2500\u2500 Request schema from FormRequest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
8565
8399
  foreach ($reflector->getParameters() as $param) {
8566
8400
  $type = $param->getType();
8567
8401
  if ($type && !$type->isBuiltin()) {
8568
8402
  $className = $type->getName();
8569
- if (is_subclass_of($className, 'IlluminateFoundationHttpFormRequest')) {
8403
+ if (is_subclass_of($className, 'Illuminate\\\\Foundation\\\\Http\\\\FormRequest')) {
8570
8404
  $request = new $className();
8571
8405
  if (method_exists($request, 'rules')) {
8572
8406
  $schema = $request->rules();
@@ -8575,96 +8409,170 @@ foreach ($routes as $route) {
8575
8409
  }
8576
8410
  }
8577
8411
 
8578
- // \u2500\u2500 Stage 1: PHP 8 Attribute on controller method \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
8579
- foreach ($reflector->getAttributes() as $attr) {
8580
- $short = class_basename($attr->getName());
8581
- if (in_array($short, ['Response', 'RouteSyncResponse'])) {
8412
+ // Parse PHP 8 Attributes for Response Metadata
8413
+ $responseMetadata = null;
8414
+ $attributes = $reflector->getAttributes();
8415
+ foreach ($attributes as $attr) {
8416
+ $attrName = $attr->getName();
8417
+ $shortName = class_basename($attrName);
8418
+
8419
+ if (in_array($shortName, ['Response', 'RouteSyncResponse'])) {
8582
8420
  $args = $attr->getArguments();
8583
- $type = $args[0] ?? $args['type'] ?? $args['model'] ?? $args['response'] ?? null;
8421
+
8422
+ $type = null;
8423
+ if (isset($args[0])) {
8424
+ $type = $args[0];
8425
+ } elseif (isset($args['type'])) {
8426
+ $type = $args['type'];
8427
+ } elseif (isset($args['model'])) {
8428
+ $type = $args['model'];
8429
+ } elseif (isset($args['response'])) {
8430
+ $type = $args['response'];
8431
+ }
8432
+
8433
+ $collection = false;
8434
+ if (isset($args[1])) {
8435
+ $collection = (bool) $args[1];
8436
+ } elseif (isset($args['collection'])) {
8437
+ $collection = (bool) $args['collection'];
8438
+ }
8439
+
8584
8440
  if ($type) {
8585
- $collection = (bool)($args[1] ?? $args['collection'] ?? false);
8586
- $responseMetadata = ['type' => class_basename($type), 'collection' => $collection];
8441
+ $responseMetadata = [
8442
+ 'type' => class_basename($type),
8443
+ 'collection' => $collection
8444
+ ];
8587
8445
  break;
8588
8446
  }
8589
8447
  }
8590
8448
  }
8591
8449
 
8592
- $methodSource = rsync_get_source($reflector);
8450
+ $fileName = $reflector->getFileName();
8451
+ $startLine = $reflector->getStartLine();
8452
+ $endLine = $reflector->getEndLine();
8453
+ $methodSource = null;
8593
8454
 
8594
- // \u2500\u2500 Stage 2: Source-based inference \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
8595
- if (!$responseMetadata) {
8596
- $responseMetadata = rsync_infer_from_source($methodSource);
8455
+ if ($fileName && $startLine !== false && $endLine !== false) {
8456
+ $lines = file($fileName);
8457
+ $methodSource = implode("", array_slice($lines, $startLine - 1, $endLine - $startLine + 1));
8597
8458
  }
8598
8459
 
8599
- // \u2500\u2500 Stage 3: Fallback $request->validate([...]) for schema \u2500\u2500
8600
- if (empty($schema) && $methodSource) {
8601
- if (preg_match('/$request->validates*(s*[(.*?)]s*)/s', $methodSource, $vm)) {
8602
- preg_match_all('/['"]([a-zA-Z0-9_.*]+)['"]s*=>s*['"]([^'"]*)['"]/', $vm[1], $rm);
8603
- foreach ($rm[1] as $i => $field) {
8604
- $schema[$field] = $rm[2][$i];
8460
+ // Resource Discovery
8461
+ if (!$responseMetadata && $methodSource) {
8462
+ $resourceName = null;
8463
+ $collection = false;
8464
+
8465
+ if (preg_match('/return\\s+new\\s+([a-zA-Z0-9_]+Resource)/', $methodSource, $matches)) {
8466
+ $resourceName = $matches[1];
8467
+ } elseif (preg_match('/return\\s+([a-zA-Z0-9_]+Resource)::collection/', $methodSource, $matches)) {
8468
+ $resourceName = $matches[1];
8469
+ $collection = true;
8470
+ }
8471
+
8472
+ if ($resourceName) {
8473
+ $resourceClass = 'App\\\\Http\\\\Resources\\\\' . $resourceName;
8474
+ if (class_exists($resourceClass)) {
8475
+ $resReflector = new ReflectionClass($resourceClass);
8476
+ $resAttrs = $resReflector->getAttributes();
8477
+ foreach ($resAttrs as $attr) {
8478
+ $shortName = class_basename($attr->getName());
8479
+ if (in_array($shortName, ['Response', 'RouteSyncResponse'])) {
8480
+ $args = $attr->getArguments();
8481
+ $type = $args[0] ?? $args['type'] ?? $args['model'] ?? $args['response'] ?? null;
8482
+ if ($type) {
8483
+ $responseMetadata = [
8484
+ 'type' => class_basename($type),
8485
+ 'collection' => $collection
8486
+ ];
8487
+ }
8488
+ }
8489
+ }
8490
+
8491
+ if (!$responseMetadata) {
8492
+ $docComment = $resReflector->getDocComment();
8493
+ if ($docComment && preg_match('/@mixin\\s+([\\\\a-zA-Z0-9_]+)/', $docComment, $mixinMatches)) {
8494
+ $responseMetadata = [
8495
+ 'type' => class_basename($mixinMatches[1]),
8496
+ 'collection' => $collection
8497
+ ];
8498
+ }
8499
+ }
8605
8500
  }
8606
8501
  }
8607
8502
  }
8608
8503
 
8609
- } catch (Exception $e) {}
8504
+ // Fallback: Try to parse $request->validate([...]) from source code
8505
+ if (empty($schema) && $methodSource) {
8506
+ if (preg_match('/\\$request->validate\\s*\\(\\s*\\[(.*?)\\]\\s*\\)/s', $methodSource, $matches)) {
8507
+ $rulesString = $matches[1];
8508
+ preg_match_all('/[\\'"]([a-zA-Z0-9_.*]+)[\\'"]\\s*=>\\s*[\\'"](.*?)[\\'"]/', $rulesString, $ruleMatches);
8509
+ if (!empty($ruleMatches[1])) {
8510
+ foreach ($ruleMatches[1] as $index => $field) {
8511
+ $schema[$field] = $ruleMatches[2][$index];
8512
+ }
8513
+ }
8514
+ }
8515
+ }
8516
+ } catch (\\Exception $e) {}
8610
8517
  }
8611
8518
  }
8612
8519
 
8613
8520
  foreach ($methods as $method) {
8614
- $nameParts = explode('/', preg_replace('/^api//', '', $route->uri()));
8615
- $resource = preg_replace('/{.*}/', '', $nameParts[0]);
8521
+ $nameParts = explode('/', preg_replace('/^api\\//', '', $route->uri()));
8522
+ $resource = preg_replace('/\\{.*\\}/', '', $nameParts[0]);
8616
8523
  if (empty($resource)) $resource = 'api';
8617
8524
 
8525
+ $name = $resource . '.' . strtolower($method);
8526
+
8618
8527
  $result['routes'][] = [
8619
- 'name' => $route->getName() ?: ($resource . '.' . strtolower($method)),
8620
- 'method' => $method,
8621
- 'path' => '/' . preg_replace('/^api//', '', $route->uri()),
8622
- 'auth' => $auth,
8528
+ 'name' => $route->getName() ?: $name,
8529
+ 'method' => $method,
8530
+ 'path' => '/' . preg_replace('/^api\\//', '', $route->uri()),
8531
+ 'auth' => $auth,
8623
8532
  'middleware' => $middlewares,
8624
- 'schema' => empty($schema) ? null : ['rules' => $schema],
8625
- 'response' => $responseMetadata,
8533
+ 'schema' => empty($schema) ? null : ['rules' => $schema],
8534
+ 'response' => $responseMetadata
8626
8535
  ];
8627
8536
  }
8628
8537
  }
8629
8538
 
8630
- // \u2500\u2500\u2500 Extract Models \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
8631
-
8539
+ // Extract Models if requested
8632
8540
  $extractModels = ${extractModels};
8633
8541
  if ($extractModels) {
8634
8542
  $modelsPath = app_path('Models');
8635
8543
  if (is_dir($modelsPath)) {
8636
- $files = IlluminateSupportFacadesFile::allFiles($modelsPath);
8544
+ $files = \\Illuminate\\Support\\Facades\\File::allFiles($modelsPath);
8637
8545
  foreach ($files as $file) {
8638
- $class = 'App\\Models\\' . str_replace('/', '\\', $file->getRelativePathname());
8639
- $class = preg_replace('/.php$/', '', $class);
8546
+ $class = 'App\\\\Models\\\\' . str_replace('/', '\\\\', $file->getRelativePathname());
8547
+ $class = preg_replace('/\\.php$/', '', $class);
8640
8548
 
8641
- if (class_exists($class) && is_subclass_of($class, 'Illuminate\\Database\\Eloquent\\Model')) {
8549
+ if (class_exists($class) && is_subclass_of($class, 'Illuminate\\\\Database\\\\Eloquent\\\\Model')) {
8642
8550
  try {
8643
8551
  $reflection = new ReflectionClass($class);
8644
8552
  if ($reflection->isAbstract()) continue;
8645
8553
 
8646
- $model = new $class();
8647
- $table = $model->getTable();
8648
- $columns = IlluminateSupportFacadesSchema::getColumns($table);
8554
+ $model = new $class();
8555
+ $table = $model->getTable();
8556
+ $columns = \\Illuminate\\Support\\Facades\\Schema::getColumns($table);
8649
8557
 
8650
8558
  $parsedColumns = [];
8651
8559
  foreach ($columns as $col) {
8652
8560
  $parsedColumns[] = [
8653
- 'name' => $col['name'],
8654
- 'type' => $col['type'],
8655
- 'nullable' => $col['nullable'],
8561
+ 'name' => $col['name'],
8562
+ 'type' => $col['type'],
8563
+ 'nullable' => $col['nullable']
8656
8564
  ];
8657
8565
  }
8658
8566
 
8659
8567
  $result['models'][] = [
8660
- 'name' => class_basename($class),
8661
- 'table' => $table,
8568
+ 'name' => class_basename($class),
8569
+ 'table' => $table,
8662
8570
  'columns' => $parsedColumns,
8663
- 'hidden' => $model->getHidden(),
8571
+ 'hidden' => $model->getHidden(),
8664
8572
  'appends' => $model->getAppends(),
8665
- 'casts' => $model->getCasts(),
8573
+ 'casts' => $model->getCasts()
8666
8574
  ];
8667
- } catch (Exception $e) {}
8575
+ } catch (\\Exception $e) {}
8668
8576
  }
8669
8577
  }
8670
8578
  }
@@ -8675,13 +8583,16 @@ echo json_encode($result);
8675
8583
  const scriptPath = import_path.default.join(projectRoot, "routesync-extractor-temp.php");
8676
8584
  try {
8677
8585
  await import_fs_extra.default.writeFile(scriptPath, phpScript);
8678
- const stdout = (0, import_child_process.execSync)(`php routesync-extractor-temp.php`, {
8586
+ const stdout = (0, import_child_process.execSync)(`php routesync-extractor-temp.php 2>/dev/null`, {
8679
8587
  cwd: projectRoot,
8680
8588
  encoding: "utf-8",
8681
8589
  maxBuffer: 1024 * 1024 * 10
8682
8590
  });
8683
8591
  await import_fs_extra.default.remove(scriptPath);
8684
- const parsed = JSON.parse(stdout);
8592
+ const trimmed = stdout.trim();
8593
+ const jsonStart = trimmed.indexOf("{");
8594
+ if (jsonStart === -1) throw new Error("No JSON output from PHP script");
8595
+ const parsed = JSON.parse(trimmed.slice(jsonStart));
8685
8596
  return {
8686
8597
  routes: parsed.routes || [],
8687
8598
  models: parsed.models || []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "routesync",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "description": "Laravel routes to typed frontend SDKs.",
5
5
  "main": "./dist/sdk.js",
6
6
  "module": "./dist/sdk.mjs",