periplus-map 0.2.1__py3-none-any.whl

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 (272) hide show
  1. periplus/__init__.py +70 -0
  2. periplus/checkmap.py +80 -0
  3. periplus/cli.py +658 -0
  4. periplus/contract/schema/map.schema.json +138 -0
  5. periplus/contract/schema/navigation.schema.json +200 -0
  6. periplus/contract/schema/pack-file.schema.json +1405 -0
  7. periplus/contract/schema/pack-manifest.schema.json +245 -0
  8. periplus/contract/schema/project-settings.schema.json +85 -0
  9. periplus/contract/spec/engine.md +151 -0
  10. periplus/contract/spec/rules.md +352 -0
  11. periplus/detect.py +228 -0
  12. periplus/engine/__init__.py +5 -0
  13. periplus/engine/check.py +481 -0
  14. periplus/engine/emit.py +368 -0
  15. periplus/engine/packload.py +2321 -0
  16. periplus/engine/pattern.py +27 -0
  17. periplus/engine/rules.py +1946 -0
  18. periplus/engine/select.py +491 -0
  19. periplus/engine/source.py +172 -0
  20. periplus/engine/tree.py +424 -0
  21. periplus/errors.py +332 -0
  22. periplus/init.py +358 -0
  23. periplus/layout.py +28 -0
  24. periplus/manifest.py +498 -0
  25. periplus/map.py +364 -0
  26. periplus/navigate/__init__.py +1 -0
  27. periplus/navigate/find.py +143 -0
  28. periplus/navigate/ids.py +30 -0
  29. periplus/navigate/listing.py +42 -0
  30. periplus/navigate/mapfile.py +189 -0
  31. periplus/navigate/path.py +175 -0
  32. periplus/navigate/show.py +175 -0
  33. periplus/navigate/types.py +83 -0
  34. periplus/navigate/walk.py +138 -0
  35. periplus/packs/advancedqueue_basic@0.0.1/pack.yaml +14 -0
  36. periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type.yaml +9 -0
  37. periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type_annotation.yaml +43 -0
  38. periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type_attribute.yaml +43 -0
  39. periplus/packs/ai_basic@0.0.1/ai_agent/ai_agent.yaml +8 -0
  40. periplus/packs/ai_basic@0.0.1/ai_agent/ai_agent_attribute.yaml +43 -0
  41. periplus/packs/ai_basic@0.0.1/ai_function_call/ai_function_call.yaml +8 -0
  42. periplus/packs/ai_basic@0.0.1/ai_function_call/ai_function_call_attribute.yaml +43 -0
  43. periplus/packs/ai_basic@0.0.1/pack.yaml +15 -0
  44. periplus/packs/config_pages_basic@0.0.1/bundle/config_pages_bundle_config.yaml +54 -0
  45. periplus/packs/config_pages_basic@0.0.1/pack.yaml +11 -0
  46. periplus/packs/crop_basic@0.0.1/bundle/crop_bundle_config.yaml +54 -0
  47. periplus/packs/crop_basic@0.0.1/pack.yaml +11 -0
  48. periplus/packs/drupal@0.1.0/block/block_placement.yaml +25 -0
  49. periplus/packs/drupal@0.1.0/block/block_placement_code.yaml +58 -0
  50. periplus/packs/drupal@0.1.0/block/block_placement_config.yaml +53 -0
  51. periplus/packs/drupal@0.1.0/block/block_plugin.yaml +52 -0
  52. periplus/packs/drupal@0.1.0/block/block_plugin_altered.yaml +61 -0
  53. periplus/packs/drupal@0.1.0/block/block_plugin_annotation.yaml +69 -0
  54. periplus/packs/drupal@0.1.0/block/block_plugin_attribute.yaml +56 -0
  55. periplus/packs/drupal@0.1.0/block/block_plugin_content.yaml +46 -0
  56. periplus/packs/drupal@0.1.0/block/block_plugin_derived.yaml +110 -0
  57. periplus/packs/drupal@0.1.0/block/block_plugin_deriver.yaml +30 -0
  58. periplus/packs/drupal@0.1.0/block/block_type.yaml +14 -0
  59. periplus/packs/drupal@0.1.0/block/block_type_code.yaml +43 -0
  60. periplus/packs/drupal@0.1.0/block/block_type_config.yaml +45 -0
  61. periplus/packs/drupal@0.1.0/cache/cache.yaml +18 -0
  62. periplus/packs/drupal@0.1.0/cache/cache_backend.yaml +31 -0
  63. periplus/packs/drupal@0.1.0/component/sdc.yaml +19 -0
  64. periplus/packs/drupal@0.1.0/component/sdc_definition.yaml +25 -0
  65. periplus/packs/drupal@0.1.0/component/sdc_use.yaml +25 -0
  66. periplus/packs/drupal@0.1.0/config/config_object.yaml +65 -0
  67. periplus/packs/drupal@0.1.0/display/display.yaml +32 -0
  68. periplus/packs/drupal@0.1.0/display/display_code.yaml +53 -0
  69. periplus/packs/drupal@0.1.0/display/display_config.yaml +95 -0
  70. periplus/packs/drupal@0.1.0/entity/entity.yaml +33 -0
  71. periplus/packs/drupal@0.1.0/entity/entity_class.yaml +60 -0
  72. periplus/packs/drupal@0.1.0/entity/entity_save.yaml +27 -0
  73. periplus/packs/drupal@0.1.0/entity/entity_type_annotation.yaml +85 -0
  74. periplus/packs/drupal@0.1.0/entity/entity_type_attribute.yaml +76 -0
  75. periplus/packs/drupal@0.1.0/field/field_instance_code.yaml +40 -0
  76. periplus/packs/drupal@0.1.0/field/field_instance_config.yaml +58 -0
  77. periplus/packs/drupal@0.1.0/field/field_storage.yaml +37 -0
  78. periplus/packs/drupal@0.1.0/field/field_storage_code.yaml +39 -0
  79. periplus/packs/drupal@0.1.0/field/field_storage_config.yaml +24 -0
  80. periplus/packs/drupal@0.1.0/form/form.yaml +48 -0
  81. periplus/packs/drupal@0.1.0/form/form_class.yaml +50 -0
  82. periplus/packs/drupal@0.1.0/form/form_id.yaml +48 -0
  83. periplus/packs/drupal@0.1.0/form/form_methods.yaml +39 -0
  84. periplus/packs/drupal@0.1.0/hook/hook.yaml +8 -0
  85. periplus/packs/drupal@0.1.0/hook/hook_attribute.yaml +28 -0
  86. periplus/packs/drupal@0.1.0/module/module.yaml +8 -0
  87. periplus/packs/drupal@0.1.0/module/module_info.yaml +50 -0
  88. periplus/packs/drupal@0.1.0/pack.yaml +184 -0
  89. periplus/packs/drupal@0.1.0/plugin/plugin.yaml +17 -0
  90. periplus/packs/drupal@0.1.0/plugin/plugin_annotation.yaml +120 -0
  91. periplus/packs/drupal@0.1.0/recommendations/recommendations.yaml +14 -0
  92. periplus/packs/drupal@0.1.0/service/service.yaml +19 -0
  93. periplus/packs/drupal@0.1.0/service/service_autowire.yaml +28 -0
  94. periplus/packs/drupal@0.1.0/service/service_definition.yaml +24 -0
  95. periplus/packs/drupal@0.1.0/service/service_use.yaml +43 -0
  96. periplus/packs/drupal_basic@0.3.0/action/action.yaml +9 -0
  97. periplus/packs/drupal_basic@0.3.0/action/action_annotation.yaml +43 -0
  98. periplus/packs/drupal_basic@0.3.0/action/action_attribute.yaml +43 -0
  99. periplus/packs/drupal_basic@0.3.0/block/block_placement.yaml +16 -0
  100. periplus/packs/drupal_basic@0.3.0/block/block_placement_config.yaml +51 -0
  101. periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin.yaml +14 -0
  102. periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin_annotation.yaml +47 -0
  103. periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin_attribute.yaml +43 -0
  104. periplus/packs/drupal_basic@0.3.0/block_type/block_type.yaml +8 -0
  105. periplus/packs/drupal_basic@0.3.0/block_type/block_type_config.yaml +54 -0
  106. periplus/packs/drupal_basic@0.3.0/boundary/boundary_types.yaml +19 -0
  107. periplus/packs/drupal_basic@0.3.0/bundle/bundle.yaml +20 -0
  108. periplus/packs/drupal_basic@0.3.0/bundle/bundle_config.yaml +393 -0
  109. periplus/packs/drupal_basic@0.3.0/call/call.yaml +349 -0
  110. periplus/packs/drupal_basic@0.3.0/component/component.yaml +30 -0
  111. periplus/packs/drupal_basic@0.3.0/config/config_object.yaml +119 -0
  112. periplus/packs/drupal_basic@0.3.0/constraint/constraint.yaml +8 -0
  113. periplus/packs/drupal_basic@0.3.0/constraint/constraint_annotation.yaml +43 -0
  114. periplus/packs/drupal_basic@0.3.0/constraint/constraint_attribute.yaml +43 -0
  115. periplus/packs/drupal_basic@0.3.0/display/display.yaml +30 -0
  116. periplus/packs/drupal_basic@0.3.0/display/display_config.yaml +203 -0
  117. periplus/packs/drupal_basic@0.3.0/display/display_mode_config.yaml +60 -0
  118. periplus/packs/drupal_basic@0.3.0/entity_type/config_entity_type_annotation.yaml +46 -0
  119. periplus/packs/drupal_basic@0.3.0/entity_type/config_entity_type_attribute.yaml +43 -0
  120. periplus/packs/drupal_basic@0.3.0/entity_type/content_entity_type_annotation.yaml +46 -0
  121. periplus/packs/drupal_basic@0.3.0/entity_type/content_entity_type_attribute.yaml +43 -0
  122. periplus/packs/drupal_basic@0.3.0/entity_type/entity_type.yaml +16 -0
  123. periplus/packs/drupal_basic@0.3.0/field/field_instance_config.yaml +116 -0
  124. periplus/packs/drupal_basic@0.3.0/field/field_storage.yaml +21 -0
  125. periplus/packs/drupal_basic@0.3.0/field/field_storage_config.yaml +45 -0
  126. periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter.yaml +8 -0
  127. periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter_annotation.yaml +46 -0
  128. periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter_attribute.yaml +43 -0
  129. periplus/packs/drupal_basic@0.3.0/field_type/field_type_annotation.yaml +46 -0
  130. periplus/packs/drupal_basic@0.3.0/field_type/field_type_attribute.yaml +50 -0
  131. periplus/packs/drupal_basic@0.3.0/field_widget/field_widget_annotation.yaml +46 -0
  132. periplus/packs/drupal_basic@0.3.0/field_widget/field_widget_attribute.yaml +50 -0
  133. periplus/packs/drupal_basic@0.3.0/form/form_id.yaml +80 -0
  134. periplus/packs/drupal_basic@0.3.0/hook/hook.yaml +100 -0
  135. periplus/packs/drupal_basic@0.3.0/hook/hook_attribute.yaml +64 -0
  136. periplus/packs/drupal_basic@0.3.0/hook/hook_theme_include.yaml +34 -0
  137. periplus/packs/drupal_basic@0.3.0/library/library.yaml +12 -0
  138. periplus/packs/drupal_basic@0.3.0/library/library_definition.yaml +58 -0
  139. periplus/packs/drupal_basic@0.3.0/local_action/local_action.yaml +12 -0
  140. periplus/packs/drupal_basic@0.3.0/local_action/local_action_definition.yaml +49 -0
  141. periplus/packs/drupal_basic@0.3.0/mail/mail.yaml +8 -0
  142. periplus/packs/drupal_basic@0.3.0/mail/mail_attribute.yaml +43 -0
  143. periplus/packs/drupal_basic@0.3.0/media_source/media_source.yaml +8 -0
  144. periplus/packs/drupal_basic@0.3.0/media_source/media_source_annotation.yaml +43 -0
  145. periplus/packs/drupal_basic@0.3.0/media_source/media_source_attribute.yaml +79 -0
  146. periplus/packs/drupal_basic@0.3.0/menu_link/menu_link.yaml +18 -0
  147. periplus/packs/drupal_basic@0.3.0/menu_link/menu_link_definition.yaml +48 -0
  148. periplus/packs/drupal_basic@0.3.0/module/module.yaml +7 -0
  149. periplus/packs/drupal_basic@0.3.0/module/module_info.yaml +58 -0
  150. periplus/packs/drupal_basic@0.3.0/pack.yaml +528 -0
  151. periplus/packs/drupal_basic@0.3.0/permission/permission.yaml +7 -0
  152. periplus/packs/drupal_basic@0.3.0/permission/permission_definition.yaml +27 -0
  153. periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker.yaml +9 -0
  154. periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker_annotation.yaml +43 -0
  155. periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker_attribute.yaml +43 -0
  156. periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource.yaml +8 -0
  157. periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource_annotation.yaml +43 -0
  158. periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource_attribute.yaml +43 -0
  159. periplus/packs/drupal_basic@0.3.0/role/role.yaml +14 -0
  160. periplus/packs/drupal_basic@0.3.0/role/role_config.yaml +44 -0
  161. periplus/packs/drupal_basic@0.3.0/route/route.yaml +42 -0
  162. periplus/packs/drupal_basic@0.3.0/route/route_definition.yaml +113 -0
  163. periplus/packs/drupal_basic@0.3.0/route/route_options.yaml +55 -0
  164. periplus/packs/drupal_basic@0.3.0/route/route_requirements.yaml +108 -0
  165. periplus/packs/drupal_basic@0.3.0/service/service.yaml +56 -0
  166. periplus/packs/drupal_basic@0.3.0/service/service_definition.yaml +181 -0
  167. periplus/packs/drupal_basic@0.3.0/template/template.yaml +86 -0
  168. periplus/packs/drupal_basic@0.3.0/template/template_route_link.yaml +30 -0
  169. periplus/packs/drupal_basic@0.3.0/theme/theme.yaml +15 -0
  170. periplus/packs/drupal_basic@0.3.0/theme/theme_info.yaml +61 -0
  171. periplus/packs/drupal_basic@0.3.0/theme_hook/template_suggestion.yaml +29 -0
  172. periplus/packs/drupal_basic@0.3.0/theme_hook/theme_hook.yaml +87 -0
  173. periplus/packs/drupal_basic@0.3.0/theme_hook/theme_hook_render.yaml +20 -0
  174. periplus/packs/drupal_basic@0.3.0/url/url.yaml +88 -0
  175. periplus/packs/drupal_basic@0.3.0/views_plugin/views_field_attribute.yaml +80 -0
  176. periplus/packs/drupal_basic@0.3.0/views_plugin/views_filter_attribute.yaml +80 -0
  177. periplus/packs/drupal_basic@0.3.0/views_plugin/views_plugin.yaml +15 -0
  178. periplus/packs/drupal_basic@0.3.0/views_plugin/views_style_attribute.yaml +80 -0
  179. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment.yaml +12 -0
  180. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_php.yaml +15 -0
  181. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_php_array.yaml +52 -0
  182. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_twig.yaml +26 -0
  183. periplus/packs/drupal_js_basic@0.0.1/attachment/php_function_holder.yaml +13 -0
  184. periplus/packs/drupal_js_basic@0.0.1/behavior/behavior.yaml +198 -0
  185. periplus/packs/drupal_js_basic@0.0.1/pack.yaml +153 -0
  186. periplus/packs/drupal_js_basic@0.0.1/setting/setting.yaml +13 -0
  187. periplus/packs/drupal_js_basic@0.0.1/setting/setting_in_js.yaml +15 -0
  188. periplus/packs/drupal_js_basic@0.0.1/setting/setting_in_php.yaml +92 -0
  189. periplus/packs/drush_basic@0.0.1/command/command.yaml +15 -0
  190. periplus/packs/drush_basic@0.0.1/command/command_annotation.yaml +60 -0
  191. periplus/packs/drush_basic@0.0.1/command/command_attribute.yaml +88 -0
  192. periplus/packs/drush_basic@0.0.1/pack.yaml +29 -0
  193. periplus/packs/eck_basic@0.0.1/bundle/eck_bundle_config.yaml +56 -0
  194. periplus/packs/eck_basic@0.0.1/entity_type/eck_entity_type_config.yaml +26 -0
  195. periplus/packs/eck_basic@0.0.1/pack.yaml +28 -0
  196. periplus/packs/go@0.0.2/interfaces/satisfies.yaml +47 -0
  197. periplus/packs/go@0.0.2/pack.yaml +51 -0
  198. periplus/packs/go@0.0.2/types/find_declarations.yaml +137 -0
  199. periplus/packs/go@0.0.2/types/node_types.yaml +36 -0
  200. periplus/packs/go_basic@0.0.3/pack.yaml +104 -0
  201. periplus/packs/go_basic@0.0.3/rules/calls.yaml +25 -0
  202. periplus/packs/go_basic@0.0.3/rules/declarations.yaml +40 -0
  203. periplus/packs/go_basic@0.0.3/rules/imports.yaml +16 -0
  204. periplus/packs/go_basic@0.0.3/types/node_types.yaml +15 -0
  205. periplus/packs/js_basic@0.0.1/function/function.yaml +68 -0
  206. periplus/packs/js_basic@0.0.1/pack.yaml +50 -0
  207. periplus/packs/laravel_basic@0.0.5/pack.yaml +313 -0
  208. periplus/packs/laravel_basic@0.0.5/rules/classes.yaml +42 -0
  209. periplus/packs/laravel_basic@0.0.5/rules/config.yaml +229 -0
  210. periplus/packs/laravel_basic@0.0.5/rules/routes.yaml +210 -0
  211. periplus/packs/laravel_basic@0.0.5/rules/types.yaml +50 -0
  212. periplus/packs/laravel_basic@0.0.5/rules/views.yaml +100 -0
  213. periplus/packs/paragraphs_basic@0.0.1/bundle/paragraph_bundle_config.yaml +54 -0
  214. periplus/packs/paragraphs_basic@0.0.1/pack.yaml +12 -0
  215. periplus/packs/php@0.1.0/edges/edge_kinds.yaml +64 -0
  216. periplus/packs/php@0.1.0/edges/find_calls.yaml +34 -0
  217. periplus/packs/php@0.1.0/edges/find_imports.yaml +18 -0
  218. periplus/packs/php@0.1.0/edges/find_member_access.yaml +22 -0
  219. periplus/packs/php@0.1.0/edges/find_structure.yaml +38 -0
  220. periplus/packs/php@0.1.0/embedded/embedded_regions.yaml +19 -0
  221. periplus/packs/php@0.1.0/imports/imports.yaml +20 -0
  222. periplus/packs/php@0.1.0/pack.yaml +117 -0
  223. periplus/packs/php@0.1.0/resolution/excluded_tokens.yaml +23 -0
  224. periplus/packs/php@0.1.0/resolution/resolution.yaml +35 -0
  225. periplus/packs/php@0.1.0/types/find_declarations.yaml +102 -0
  226. periplus/packs/php@0.1.0/types/node_types.yaml +55 -0
  227. periplus/packs/php_basic@0.2.0/edges/edge_kinds.yaml +48 -0
  228. periplus/packs/php_basic@0.2.0/edges/find_structure.yaml +750 -0
  229. periplus/packs/php_basic@0.2.0/imports/imports.yaml +19 -0
  230. periplus/packs/php_basic@0.2.0/pack.yaml +94 -0
  231. periplus/packs/php_basic@0.2.0/types/find_declarations.yaml +267 -0
  232. periplus/packs/php_basic@0.2.0/types/node_types.yaml +55 -0
  233. periplus/packs/profile_basic@0.0.1/bundle/profile_bundle_config.yaml +54 -0
  234. periplus/packs/profile_basic@0.0.1/pack.yaml +12 -0
  235. periplus/packs/salesforce_basic@0.0.1/event/salesforce_event.yaml +36 -0
  236. periplus/packs/salesforce_basic@0.0.1/pack.yaml +31 -0
  237. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping/salesforce_mapping.yaml +19 -0
  238. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping/salesforce_mapping_config.yaml +83 -0
  239. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping_field/salesforce_mapping_field.yaml +8 -0
  240. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping_field/salesforce_mapping_field_annotation.yaml +43 -0
  241. periplus/packs/twig@0.0.1/pack.yaml +26 -0
  242. periplus/packs/twig@0.0.1/types/template.yaml +57 -0
  243. periplus/packs/twig_basic@0.1.0/pack.yaml +11 -0
  244. periplus/packs/twig_tweak_basic@0.0.1/pack.yaml +27 -0
  245. periplus/packs/twig_tweak_basic@0.0.1/rules/block.yaml +20 -0
  246. periplus/packs/twig_tweak_basic@0.0.1/rules/entity.yaml +35 -0
  247. periplus/packs/twig_tweak_basic@0.0.1/rules/field.yaml +21 -0
  248. periplus/packs/twig_tweak_basic@0.0.1/rules/menu.yaml +21 -0
  249. periplus/packs/webform_basic@0.0.1/bundle/webform_submission_bundle_config.yaml +54 -0
  250. periplus/packs/webform_basic@0.0.1/pack.yaml +20 -0
  251. periplus/packs/webform_basic@0.0.1/webform_handler/webform_handler.yaml +8 -0
  252. periplus/packs/webform_basic@0.0.1/webform_handler/webform_handler_annotation.yaml +43 -0
  253. periplus/packs/yaml@0.0.1/pack.yaml +72 -0
  254. periplus/packs/yaml@0.0.1/types/find_mapping_entry.yaml +21 -0
  255. periplus/packs/yaml@0.0.1/types/yaml_types.yaml +44 -0
  256. periplus/packs/yaml_basic@0.1.0/pack.yaml +10 -0
  257. periplus/packs.py +447 -0
  258. periplus/preflight.py +102 -0
  259. periplus/py.typed +0 -0
  260. periplus/report.py +596 -0
  261. periplus/resolution.py +355 -0
  262. periplus/settings.py +617 -0
  263. periplus/settings.stub.yml +99 -0
  264. periplus/spec.py +774 -0
  265. periplus/update.py +197 -0
  266. periplus/validate.py +655 -0
  267. periplus_map-0.2.1.dist-info/METADATA +566 -0
  268. periplus_map-0.2.1.dist-info/RECORD +272 -0
  269. periplus_map-0.2.1.dist-info/WHEEL +4 -0
  270. periplus_map-0.2.1.dist-info/entry_points.txt +2 -0
  271. periplus_map-0.2.1.dist-info/licenses/LICENSE +202 -0
  272. periplus_map-0.2.1.dist-info/licenses/NOTICE +2 -0
@@ -0,0 +1,229 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # A config file, named by its file: config/app.php is app, the first segment of config('app.name').
4
+ # Each text key of the array it returns, app.name, and a migration, named by its file.
5
+
6
+ rules:
7
+
8
+ - rule: config_file
9
+ reads: file
10
+ in: [config_files]
11
+ match: {file: '*', filetype: php}
12
+ id: {from: file_stem}
13
+ emits: [{node: {type: laravel.config}}]
14
+ confidence: declared
15
+
16
+ # The route_file type claims every file named api.php, web.php, channels.php or console.php at any
17
+ # depth, so a config file of one of those names is read as text, not as php. A type claimed by a
18
+ # whole name has no ending, so its stem is the whole name, api.php.
19
+ - rule: config_file_named_like_routes
20
+ reads: file
21
+ in: [config_files]
22
+ match: {file: '*', filetype: route_file}
23
+ id: {from: file_stem, normalize: [{replace: '\.php$', with: ''}]}
24
+ emits: [{node: {type: laravel.config}}]
25
+ confidence: declared
26
+
27
+ # A key named by the config file alone, app for config/app.php, with a key_of edge to the file: it
28
+ # stands for the whole array the file returns, so that config('app') ends on it.
29
+ - rule: config_file_key
30
+ reads: file
31
+ in: [config_files]
32
+ match: {file: '*', filetype: config_text, text: '\A'}
33
+ id: {template: '{config_name}'}
34
+ emits: [{node: {type: laravel.config_key}}]
35
+ confidence: declared
36
+
37
+ - rule: config_file_key_of
38
+ reads: file
39
+ in: [config_files]
40
+ match: {file: '*', filetype: config_text, text: '\A'}
41
+ id: {template: '{config_name}'}
42
+ emits: [{edge: {kind: key_of, from: this_node, to: {template: '{config_name}', types: [laravel.config]}}}]
43
+ confidence: declared
44
+
45
+ - rule: config_file_key_named_like_routes
46
+ reads: file
47
+ in: [config_files]
48
+ match: {file: '*', filetype: route_file, text: '\A'}
49
+ id: {template: '{route_file}'}
50
+ emits: [{node: {type: laravel.config_key}}]
51
+ confidence: declared
52
+
53
+ - rule: config_file_key_of_named_like_routes
54
+ reads: file
55
+ in: [config_files]
56
+ match: {file: '*', filetype: route_file, text: '\A'}
57
+ id: {template: '{route_file}'}
58
+ emits: [{edge: {kind: key_of, from: this_node, to: {template: '{route_file}', types: [laravel.config]}}}]
59
+ confidence: declared
60
+
61
+ # Each text key of the array a config file returns, named by the file and every enclosing key:
62
+ # 'one' => ['two' => 1] in config/app.php is app.one.two, with a key_of edge to the config app.
63
+ # The match starts on the character before the key's quote, as the config_key span of a key whose
64
+ # value is an array does, so that span holds its own key: value, an array or nothing, says so, and
65
+ # parents leaves that key out. guard is a dot when the spans that hold the key allow a node (see
66
+ # config_text in pack.yaml) and no key on the way holds a dot; otherwise it is empty and the id
67
+ # makes nothing. The four rules differ only in their file type and the name of the file's value.
68
+ - rule: config_key_decl
69
+ reads: file
70
+ in: [config_files]
71
+ match:
72
+ file: '*'
73
+ filetype: config_text
74
+ text: '[\[,(\s](?<q>[''"])(?<key>(?:(?!(?P=q))[^\\$])+)(?P=q)(?=\s*=>\s*(?<value>(?:(?!\[(?:[^\[\]]|\[(?:[^\[\]]|\[[^\[\]]*\])*\])*\]\s*\[)\[)?))'
75
+ values:
76
+ returns: {from: {enclosing: config_return, capture: word}}
77
+ brackets: {from: {enclosing: config_bracket, capture: at}, normalize: [{replace: '.', with: 'x'}]}
78
+ own: {from: {capture: value}, normalize: [{replace: '.', with: 'x'}]}
79
+ keyed: {from: {enclosing: config_key, capture: arrow}, normalize: [{replace: '.', with: 'x'}]}
80
+ parens: {from: {enclosing: config_paren, capture: at}}
81
+ braces: {from: {enclosing: config_brace, capture: at}}
82
+ path: {from: {enclosing: config_key, capture: key}}
83
+ guard: {template: '{returns}|{brackets}{own}|{keyed}x|{parens}{braces}|{path}{key}', normalize: [{replace: '(?s)^return\|(x*)\|\1\|\|[^.]*$', with: '.'}, {replace: '(?s)^(?!\.$).*', with: ''}]}
84
+ keys: {from: {enclosing: config_key, capture: key}, join: '.'}
85
+ head: {template: '{guard}${config_name}.{keys}${own}', normalize: [{replace: '(?s)^\$.*', with: ''}, {replace: '[^.$]*\$x$', with: ''}, {replace: '(?<!\.)\$$', with: '.'}, {replace: '\$$', with: ''}, {replace: '^\.\$', with: ''}]}
86
+ id: {template: '{head}{key}'}
87
+ line: {capture: key}
88
+ emits: [{node: {type: laravel.config_key}}]
89
+ confidence: declared
90
+
91
+ - rule: config_key_decl_of
92
+ reads: file
93
+ in: [config_files]
94
+ match:
95
+ file: '*'
96
+ filetype: config_text
97
+ text: '[\[,(\s](?<q>[''"])(?<key>(?:(?!(?P=q))[^\\$])+)(?P=q)(?=\s*=>\s*(?<value>(?:(?!\[(?:[^\[\]]|\[(?:[^\[\]]|\[[^\[\]]*\])*\])*\]\s*\[)\[)?))'
98
+ values:
99
+ returns: {from: {enclosing: config_return, capture: word}}
100
+ brackets: {from: {enclosing: config_bracket, capture: at}, normalize: [{replace: '.', with: 'x'}]}
101
+ own: {from: {capture: value}, normalize: [{replace: '.', with: 'x'}]}
102
+ keyed: {from: {enclosing: config_key, capture: arrow}, normalize: [{replace: '.', with: 'x'}]}
103
+ parens: {from: {enclosing: config_paren, capture: at}}
104
+ braces: {from: {enclosing: config_brace, capture: at}}
105
+ path: {from: {enclosing: config_key, capture: key}}
106
+ guard: {template: '{returns}|{brackets}{own}|{keyed}x|{parens}{braces}|{path}{key}', normalize: [{replace: '(?s)^return\|(x*)\|\1\|\|[^.]*$', with: '.'}, {replace: '(?s)^(?!\.$).*', with: ''}]}
107
+ keys: {from: {enclosing: config_key, capture: key}, join: '.'}
108
+ head: {template: '{guard}${config_name}.{keys}${own}', normalize: [{replace: '(?s)^\$.*', with: ''}, {replace: '[^.$]*\$x$', with: ''}, {replace: '(?<!\.)\$$', with: '.'}, {replace: '\$$', with: ''}, {replace: '^\.\$', with: ''}]}
109
+ id: {template: '{head}{key}'}
110
+ emits:
111
+ - edge:
112
+ kind: key_of
113
+ from: this_node
114
+ to: {template: '{config_name}', types: [laravel.config], on_miss: unresolved}
115
+ confidence: declared
116
+
117
+ # The same, in a config file the route_file type claims by its name: config/api.php is api.
118
+ - rule: config_key_decl_named_like_routes
119
+ reads: file
120
+ in: [config_files]
121
+ match:
122
+ file: '*'
123
+ filetype: route_file
124
+ text: '[\[,(\s](?<q>[''"])(?<key>(?:(?!(?P=q))[^\\$])+)(?P=q)(?=\s*=>\s*(?<value>(?:(?!\[(?:[^\[\]]|\[(?:[^\[\]]|\[[^\[\]]*\])*\])*\]\s*\[)\[)?))'
125
+ values:
126
+ returns: {from: {enclosing: config_return, capture: word}}
127
+ brackets: {from: {enclosing: config_bracket, capture: at}, normalize: [{replace: '.', with: 'x'}]}
128
+ own: {from: {capture: value}, normalize: [{replace: '.', with: 'x'}]}
129
+ keyed: {from: {enclosing: config_key, capture: arrow}, normalize: [{replace: '.', with: 'x'}]}
130
+ parens: {from: {enclosing: config_paren, capture: at}}
131
+ braces: {from: {enclosing: config_brace, capture: at}}
132
+ path: {from: {enclosing: config_key, capture: key}}
133
+ guard: {template: '{returns}|{brackets}{own}|{keyed}x|{parens}{braces}|{path}{key}', normalize: [{replace: '(?s)^return\|(x*)\|\1\|\|[^.]*$', with: '.'}, {replace: '(?s)^(?!\.$).*', with: ''}]}
134
+ keys: {from: {enclosing: config_key, capture: key}, join: '.'}
135
+ head: {template: '{guard}${route_file}.{keys}${own}', normalize: [{replace: '(?s)^\$.*', with: ''}, {replace: '[^.$]*\$x$', with: ''}, {replace: '(?<!\.)\$$', with: '.'}, {replace: '\$$', with: ''}, {replace: '^\.\$', with: ''}]}
136
+ id: {template: '{head}{key}'}
137
+ line: {capture: key}
138
+ emits: [{node: {type: laravel.config_key}}]
139
+ confidence: declared
140
+
141
+ - rule: config_key_decl_of_named_like_routes
142
+ reads: file
143
+ in: [config_files]
144
+ match:
145
+ file: '*'
146
+ filetype: route_file
147
+ text: '[\[,(\s](?<q>[''"])(?<key>(?:(?!(?P=q))[^\\$])+)(?P=q)(?=\s*=>\s*(?<value>(?:(?!\[(?:[^\[\]]|\[(?:[^\[\]]|\[[^\[\]]*\])*\])*\]\s*\[)\[)?))'
148
+ values:
149
+ returns: {from: {enclosing: config_return, capture: word}}
150
+ brackets: {from: {enclosing: config_bracket, capture: at}, normalize: [{replace: '.', with: 'x'}]}
151
+ own: {from: {capture: value}, normalize: [{replace: '.', with: 'x'}]}
152
+ keyed: {from: {enclosing: config_key, capture: arrow}, normalize: [{replace: '.', with: 'x'}]}
153
+ parens: {from: {enclosing: config_paren, capture: at}}
154
+ braces: {from: {enclosing: config_brace, capture: at}}
155
+ path: {from: {enclosing: config_key, capture: key}}
156
+ guard: {template: '{returns}|{brackets}{own}|{keyed}x|{parens}{braces}|{path}{key}', normalize: [{replace: '(?s)^return\|(x*)\|\1\|\|[^.]*$', with: '.'}, {replace: '(?s)^(?!\.$).*', with: ''}]}
157
+ keys: {from: {enclosing: config_key, capture: key}, join: '.'}
158
+ head: {template: '{guard}${route_file}.{keys}${own}', normalize: [{replace: '(?s)^\$.*', with: ''}, {replace: '[^.$]*\$x$', with: ''}, {replace: '(?<!\.)\$$', with: '.'}, {replace: '\$$', with: ''}, {replace: '^\.\$', with: ''}]}
159
+ id: {template: '{head}{key}'}
160
+ emits:
161
+ - edge:
162
+ kind: key_of
163
+ from: this_node
164
+ to: {template: '{route_file}', types: [laravel.config], on_miss: unresolved}
165
+ confidence: declared
166
+
167
+ # config('app.name') written in a template: an edge from the view to the key app.name, and an
168
+ # edge from the key app, named by the file, to the config file app, unresolved when no such file
169
+ # exists. The key app.name is mapped when the file declares it; otherwise it is in state
170
+ # referenced, since this_node takes no on_miss. The key is this rule's own node and the view the
171
+ # end it names, because reads_config also runs from a PHP function or method, and this_node needs
172
+ # one id namespace.
173
+ - rule: config_read_in_view
174
+ reads: file
175
+ in: [views]
176
+ match:
177
+ file: '*'
178
+ filetype: blade
179
+ text: '(?:^|[^\w>$:])config\(\s*[''"](?<key>[\w-]+[\w.-]*)[''"]\s*[,)]'
180
+ id: {from: {capture: key}}
181
+ line: {capture: key}
182
+ emits:
183
+ - edge:
184
+ kind: reads_config
185
+ from: {template: '{view}', types: [laravel.view]}
186
+ to: this_node
187
+ confidence: declared
188
+
189
+ # config('app.name') in a PHP function or method: an edge from it to the key app.name, at the
190
+ # call's line, unresolved when no config file declares that key. config('app') ends on the key app
191
+ # that stands for the file. No key_of edge: a reference rule's edges run from the function or
192
+ # method. config($key) and config(['app.name' => 'x']) give nothing and go under skipped.
193
+ - rule: config_call
194
+ reads: file
195
+ in: [source]
196
+ match:
197
+ reference: function_call_expression
198
+ name_child: function
199
+ filetype: php
200
+ where: [{name_matches: '(?i)\\?config'}]
201
+ emits:
202
+ - edge:
203
+ kind: reads_config
204
+ from: enclosing_declaration
205
+ to: {from: {argument: 0}, types: [laravel.config_key], on_miss: unresolved}
206
+ confidence: declared
207
+
208
+ - rule: config_key_in_file
209
+ reads: file
210
+ in: [views]
211
+ match:
212
+ file: '*'
213
+ filetype: blade
214
+ text: '(?:^|[^\w>$:])config\(\s*[''"](?<key>(?<file>[\w-]+)[\w.-]*)[''"]\s*[,)]'
215
+ id: {from: {capture: file}}
216
+ emits:
217
+ - edge:
218
+ kind: key_of
219
+ from: this_node
220
+ to: {from: {capture: file}, types: [laravel.config], on_miss: unresolved}
221
+ confidence: declared
222
+
223
+ - rule: migration_file
224
+ reads: file
225
+ in: [migrations]
226
+ match: {file: '*', filetype: php}
227
+ id: {from: file_stem}
228
+ emits: [{node: {type: laravel.migration}}]
229
+ confidence: declared
@@ -0,0 +1,210 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # A route, read as text from a route file, named by its file, its verb and its URI as written:
4
+ # web:GET /books/{slug}. Inside Route::prefix('admin')->group(...), the URI joins the prefixes of
5
+ # every enclosing group as Laravel does, outermost first: web:GET admin/stats. A route's name
6
+ # follows each enclosing ->name('admin.') the same way. A prefix the application adds outside the
7
+ # file (BookStack's /api) is not in the name. Two rules per route form, because a rule that emits
8
+ # an edge emits no node.
9
+
10
+ rules:
11
+
12
+ # The use statements of a route file, bound for bound_first_segment: use A\B\C binds C to A\B\C,
13
+ # use A\B as D binds D to A\B. A grouped use, use A\{B, C}, binds nothing.
14
+ - rule: route_use
15
+ reads: file
16
+ in: [routes]
17
+ match:
18
+ file: '*'
19
+ filetype: route_file
20
+ text: '(?m)^use[ \t]+\\?(?<path>\w+(?:\\\w+)*)[ \t]*;'
21
+ values:
22
+ bound: {from: {capture: path}, normalize: [{replace: '^.*\\', with: ''}]}
23
+ emits: [{binding: {name: '{bound}', target: '{path}'}}]
24
+ confidence: declared
25
+
26
+ - rule: route_use_alias
27
+ reads: file
28
+ in: [routes]
29
+ match:
30
+ file: '*'
31
+ filetype: route_file
32
+ text: '(?m)^use[ \t]+\\?(?<path>\w+(?:\\\w+)*)[ \t]+as[ \t]+(?<alias>\w+)[ \t]*;'
33
+ emits: [{binding: {name: '{alias}', target: '{path}'}}]
34
+ confidence: declared
35
+
36
+ # Route::get('/uri', ...) and the other verbs, Route::view('/uri', 'view') and
37
+ # Route::redirect('/uri', '/to'). Any handler: an array, a closure, a string.
38
+ - rule: route_verb
39
+ reads: file
40
+ in: [routes]
41
+ match:
42
+ file: '*'
43
+ filetype: route_file
44
+ text: 'Route::(?<verb>get|post|put|patch|delete|options|any|view|redirect|permanentRedirect)\(\s*[''"](?<uri>[^''"]*)[''"]'
45
+ values:
46
+ method: {from: {capture: verb}, case: upper}
47
+ prefix: {from: {enclosing: group, capture: prefix}, join: '/', normalize: [{replace: '/+', with: '/'}, {replace: '^/|/$', with: ''}]}
48
+ path: {template: '{prefix} {uri}', normalize: [{replace: '^ ', with: ''}, {replace: ' /*$', with: ''}, {replace: ' /*', with: '/'}]}
49
+ id: {template: '{route_file}:{method} {path}'}
50
+ emits:
51
+ - node: {type: laravel.route}
52
+ - attribute: {name: uri, from: {capture: uri}}
53
+ confidence: declared
54
+
55
+ # ->name('x') chained on a route, in the same statement: the route's name attribute. A text rule
56
+ # cannot emit an attribute alone, so it emits the route node again, at the same line.
57
+ - rule: route_name
58
+ reads: file
59
+ in: [routes]
60
+ match:
61
+ file: '*'
62
+ filetype: route_file
63
+ text: 'Route::(?<verb>get|post|put|patch|delete|options|any|view|redirect|permanentRedirect)\(\s*[''"](?<uri>[^''"]*)[''"][^;]*?\)\s*->name\(\s*[''"](?<name>[^''"]+)[''"]'
64
+ values:
65
+ method: {from: {capture: verb}, case: upper}
66
+ prefix: {from: {enclosing: group, capture: prefix}, join: '/', normalize: [{replace: '/+', with: '/'}, {replace: '^/|/$', with: ''}]}
67
+ path: {template: '{prefix} {uri}', normalize: [{replace: '^ ', with: ''}, {replace: ' /*$', with: ''}, {replace: ' /*', with: '/'}]}
68
+ name_prefix: {from: {enclosing: group, capture: name}}
69
+ full_name: {template: '{name_prefix}{name}'}
70
+ id: {template: '{route_file}:{method} {path}'}
71
+ emits: [{node: {type: laravel.route}}, {attribute: {name: name, from: {value: full_name}}}]
72
+ confidence: declared
73
+
74
+ - rule: fallback_name
75
+ reads: file
76
+ in: [routes]
77
+ match:
78
+ file: '*'
79
+ filetype: route_file
80
+ text: 'Route::fallback\([^;]*?\)\s*->name\(\s*[''"](?<name>[^''"]+)[''"]'
81
+ id: {template: '{route_file}:FALLBACK'}
82
+ emits: [{node: {type: laravel.route}}, {attribute: {name: name, from: {capture: name}}}]
83
+ confidence: declared
84
+
85
+ # Route::fallback(...): one per file.
86
+ - rule: route_fallback
87
+ reads: file
88
+ in: [routes]
89
+ match:
90
+ file: '*'
91
+ filetype: route_file
92
+ text: 'Route::fallback\('
93
+ id: {template: '{route_file}:FALLBACK'}
94
+ emits: [{node: {type: laravel.route}}]
95
+ confidence: declared
96
+
97
+ # The handler [Controller::class, 'method'] with a qualified class, EntityControllers\BookController:
98
+ # the first segment resolves through the file's use bindings, split on a backslash, and the rest,
99
+ # ::method included, follows it. The end is the method php_basic's find_method names
100
+ # Class::method, unresolved when no class of that name with that method is mapped.
101
+ - rule: route_handler_qualified
102
+ reads: file
103
+ in: [routes]
104
+ match:
105
+ file: '*'
106
+ filetype: route_file
107
+ text: 'Route::(?<verb>get|post|put|patch|delete|options|any)\(\s*[''"](?<uri>[^''"]*)[''"]\s*,\s*\[\s*(?<class>\\?\w+(?:\\\w+)+)::class\s*,\s*[''"](?<action>\w+)[''"]\s*\]'
108
+ values:
109
+ method: {from: {capture: verb}, case: upper}
110
+ prefix: {from: {enclosing: group, capture: prefix}, join: '/', normalize: [{replace: '/+', with: '/'}, {replace: '^/|/$', with: ''}]}
111
+ path: {template: '{prefix} {uri}', normalize: [{replace: '^ ', with: ''}, {replace: ' /*$', with: ''}, {replace: ' /*', with: '/'}]}
112
+ id: {template: '{route_file}:{method} {path}'}
113
+ emits:
114
+ - edge:
115
+ kind: handled_by
116
+ from: this_node
117
+ to: {template: '{class}::{action}', resolve: [{full_if_prefixed: '\'}, bound_first_segment, as_written], separator: '\', types: [php.method], on_miss: unresolved}
118
+ confidence: declared
119
+
120
+ # The same with a bare class, MetaController: split on a colon, the first segment is the class, and
121
+ # ::method follows the bound name.
122
+ - rule: route_handler_bare
123
+ reads: file
124
+ in: [routes]
125
+ match:
126
+ file: '*'
127
+ filetype: route_file
128
+ text: 'Route::(?<verb>get|post|put|patch|delete|options|any)\(\s*[''"](?<uri>[^''"]*)[''"]\s*,\s*\[\s*(?<class>\w+)::class\s*,\s*[''"](?<action>\w+)[''"]\s*\]'
129
+ values:
130
+ method: {from: {capture: verb}, case: upper}
131
+ prefix: {from: {enclosing: group, capture: prefix}, join: '/', normalize: [{replace: '/+', with: '/'}, {replace: '^/|/$', with: ''}]}
132
+ path: {template: '{prefix} {uri}', normalize: [{replace: '^ ', with: ''}, {replace: ' /*$', with: ''}, {replace: ' /*', with: '/'}]}
133
+ id: {template: '{route_file}:{method} {path}'}
134
+ emits:
135
+ - edge:
136
+ kind: handled_by
137
+ from: this_node
138
+ to: {template: '{class}::{action}', resolve: [bound_first_segment, as_written], separator: ':', types: [php.method], on_miss: unresolved}
139
+ confidence: declared
140
+
141
+ # Route::fallback([Controller::class, 'method']), bare class.
142
+ - rule: route_fallback_handler
143
+ reads: file
144
+ in: [routes]
145
+ match:
146
+ file: '*'
147
+ filetype: route_file
148
+ text: 'Route::fallback\(\s*\[\s*(?<class>\w+)::class\s*,\s*[''"](?<action>\w+)[''"]\s*\]'
149
+ id: {template: '{route_file}:FALLBACK'}
150
+ emits:
151
+ - edge:
152
+ kind: handled_by
153
+ from: this_node
154
+ to: {template: '{class}::{action}', resolve: [bound_first_segment, as_written], separator: ':', types: [php.method], on_miss: unresolved}
155
+ confidence: declared
156
+
157
+ # Route::view('/uri', 'dotted.view'): the route renders that view.
158
+ - rule: route_view
159
+ reads: file
160
+ in: [routes]
161
+ match:
162
+ file: '*'
163
+ filetype: route_file
164
+ text: 'Route::view\(\s*[''"](?<uri>[^''"]*)[''"]\s*,\s*[''"](?<view>[^''"]+)[''"]'
165
+ values:
166
+ prefix: {from: {enclosing: group, capture: prefix}, join: '/', normalize: [{replace: '/+', with: '/'}, {replace: '^/|/$', with: ''}]}
167
+ path: {template: '{prefix} {uri}', normalize: [{replace: '^ ', with: ''}, {replace: ' /*$', with: ''}, {replace: ' /*', with: '/'}]}
168
+ id: {template: '{route_file}:VIEW {path}'}
169
+ emits:
170
+ - edge:
171
+ kind: route_renders
172
+ from: this_node
173
+ to: {from: {capture: view}, types: [laravel.view], on_miss: unresolved}
174
+ confidence: declared
175
+
176
+ # Route::resource('photos', PhotoController::class) registers seven routes; only the resource
177
+ # itself is stated, as one node, with an edge to its controller class.
178
+ - rule: route_resource
179
+ reads: file
180
+ in: [routes]
181
+ match:
182
+ file: '*'
183
+ filetype: route_file
184
+ text: 'Route::(?<verb>resource|apiResource)\(\s*[''"](?<uri>[^''"]*)[''"]'
185
+ values:
186
+ method: {from: {capture: verb}, case: upper}
187
+ prefix: {from: {enclosing: group, capture: prefix}, join: '/', normalize: [{replace: '/+', with: '/'}, {replace: '^/|/$', with: ''}]}
188
+ path: {template: '{prefix} {uri}', normalize: [{replace: '^ ', with: ''}, {replace: ' /*$', with: ''}, {replace: ' /*', with: '/'}]}
189
+ id: {template: '{route_file}:{method} {path}'}
190
+ emits: [{node: {type: laravel.route}}]
191
+ confidence: declared
192
+
193
+ - rule: route_resource_controller
194
+ reads: file
195
+ in: [routes]
196
+ match:
197
+ file: '*'
198
+ filetype: route_file
199
+ text: 'Route::(?<verb>resource|apiResource)\(\s*[''"](?<uri>[^''"]*)[''"]\s*,\s*(?<class>\\?\w+(?:\\\w+)*)::class'
200
+ values:
201
+ method: {from: {capture: verb}, case: upper}
202
+ prefix: {from: {enclosing: group, capture: prefix}, join: '/', normalize: [{replace: '/+', with: '/'}, {replace: '^/|/$', with: ''}]}
203
+ path: {template: '{prefix} {uri}', normalize: [{replace: '^ ', with: ''}, {replace: ' /*$', with: ''}, {replace: ' /*', with: '/'}]}
204
+ id: {template: '{route_file}:{method} {path}'}
205
+ emits:
206
+ - edge:
207
+ kind: resource_controller
208
+ from: this_node
209
+ to: {from: {capture: class}, resolve: [{full_if_prefixed: '\'}, bound_first_segment, as_written], separator: '\', types: [php.class], on_miss: unresolved}
210
+ confidence: declared
@@ -0,0 +1,50 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # The node types and edge kinds this pack declares.
4
+ node_types:
5
+ - name: laravel.route
6
+ id_namespace: laravel.route
7
+ - name: laravel.view
8
+ id_namespace: laravel.view
9
+ - name: laravel.controller
10
+ id_namespace: laravel.controller
11
+ - name: laravel.model
12
+ id_namespace: laravel.model
13
+ - name: laravel.config
14
+ id_namespace: laravel.config
15
+ - name: laravel.config_key
16
+ id_namespace: laravel.config_key
17
+ - name: laravel.migration
18
+ id_namespace: laravel.migration
19
+
20
+ edge_kinds:
21
+ - kind: handled_by
22
+ from: laravel.route
23
+ to: php.method
24
+ - kind: resource_controller
25
+ from: laravel.route
26
+ to: php.class
27
+ - kind: route_renders
28
+ from: laravel.route
29
+ to: laravel.view
30
+ - kind: includes_view
31
+ from: laravel.view
32
+ to: laravel.view
33
+ - kind: extends_view
34
+ from: laravel.view
35
+ to: laravel.view
36
+ - kind: implemented_by
37
+ from: [laravel.controller, laravel.model]
38
+ to: php.class
39
+ - kind: renders
40
+ from: [php.function, php.method]
41
+ to: laravel.view
42
+ - kind: reads_config
43
+ from: [laravel.view, php.function, php.method]
44
+ to: laravel.config_key
45
+ - kind: key_of
46
+ from: laravel.config_key
47
+ to: laravel.config
48
+ - kind: uses_component
49
+ from: laravel.view
50
+ to: laravel.view
@@ -0,0 +1,100 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # A Blade view, one per template file, named by its dotted path below the views folder:
4
+ # books/show.blade.php is books.show. A view another view names by a literal is the end of an
5
+ # edge from the naming view's node, at the line of the directive; unresolved when no such file
6
+ # exists. A name written in a variable, @include($name), gives nothing. Text inside {{-- --}} is
7
+ # not read.
8
+
9
+ rules:
10
+
11
+ - rule: view_file
12
+ reads: file
13
+ in: [views]
14
+ match: {file: '*', filetype: blade}
15
+ id: {template: '{view}'}
16
+ emits: [{node: {type: laravel.view}}]
17
+ confidence: declared
18
+
19
+ # @include('x.y'), @includeIf('x.y'), @each('x.y', ...). The quote must close the argument, so a
20
+ # name built by concatenation, @include('x.' . $y), gives nothing.
21
+ - rule: view_include
22
+ reads: file
23
+ in: [views]
24
+ match:
25
+ file: '*'
26
+ filetype: blade
27
+ text: '@(?:include|includeIf|each)\(\s*[''"](?<name>[^''"]+)[''"]\s*[,)]'
28
+ id: {template: '{view}'}
29
+ emits:
30
+ - edge:
31
+ kind: includes_view
32
+ from: this_node
33
+ to: {from: {capture: name}, types: [laravel.view], on_miss: unresolved}
34
+ confidence: declared
35
+
36
+ - rule: view_extends
37
+ reads: file
38
+ in: [views]
39
+ match:
40
+ file: '*'
41
+ filetype: blade
42
+ text: '@extends\(\s*[''"](?<name>[^''"]+)[''"]\s*[,)]'
43
+ id: {template: '{view}'}
44
+ emits:
45
+ - edge:
46
+ kind: extends_view
47
+ from: this_node
48
+ to: {from: {capture: name}, types: [laravel.view], on_miss: unresolved}
49
+ confidence: declared
50
+
51
+ - rule: view_component
52
+ reads: file
53
+ in: [views]
54
+ match:
55
+ file: '*'
56
+ filetype: blade
57
+ text: '@component\(\s*[''"](?<name>[^''"]+)[''"]\s*[,)]'
58
+ id: {template: '{view}'}
59
+ emits:
60
+ - edge:
61
+ kind: includes_view
62
+ from: this_node
63
+ to: {from: {capture: name}, types: [laravel.view], on_miss: unresolved}
64
+ confidence: declared
65
+
66
+ # view('books.show') in a PHP function or method: an edge from it to that view, at the call's line;
67
+ # unresolved when no such template exists. The name is the call's first argument as written, so
68
+ # view($name) and a concatenated name give nothing and go under skipped.
69
+ - rule: view_call
70
+ reads: file
71
+ in: [source]
72
+ match:
73
+ reference: function_call_expression
74
+ name_child: function
75
+ filetype: php
76
+ where: [{name_matches: '(?i)\\?view'}]
77
+ emits:
78
+ - edge:
79
+ kind: renders
80
+ from: enclosing_declaration
81
+ to: {from: {argument: 0}, types: [laravel.view], on_miss: unresolved}
82
+ confidence: declared
83
+
84
+ # <x-alert> and <x-forms.input>: the anonymous component's view below components, so
85
+ # components.alert and components.forms.input. <x-slot> is not a component, so the name may not be
86
+ # slot; a namespaced <x-mail::message> gives nothing.
87
+ - rule: blade_component_tag
88
+ reads: file
89
+ in: [views]
90
+ match:
91
+ file: '*'
92
+ filetype: blade
93
+ text: '<x-(?<name>(?:[a-rt-z0-9_]|s[a-km-z0-9_.-]|sl[a-np-z0-9_.-]|slo[a-su-z0-9_.-]|slot[\w.-])[\w.-]*)[\s/>]'
94
+ id: {template: '{view}'}
95
+ emits:
96
+ - edge:
97
+ kind: uses_component
98
+ from: this_node
99
+ to: {template: 'components.{name}', types: [laravel.view], on_miss: unresolved}
100
+ confidence: inferred
@@ -0,0 +1,54 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # A paragraph type read from its config file as the bundle paragraph.<id>, the id drupal_basic gives a field or
4
+ # display of it. Two rules: the node with its label, and its edges.
5
+
6
+ rules:
7
+ - rule: bundle_paragraph_from_config
8
+ reads: file
9
+ in:
10
+ - config
11
+ - module_config
12
+ match:
13
+ file: paragraphs.paragraphs_type.*
14
+ filetype: yaml
15
+ id:
16
+ from: file_stem
17
+ normalize:
18
+ - {replace: '^paragraphs\.paragraphs_type\.', with: 'paragraph.'}
19
+ emits:
20
+ - node:
21
+ type: drupal.bundle
22
+ - attribute:
23
+ name: label
24
+ from:
25
+ key: label
26
+ confidence: declared
27
+ - rule: bundle_paragraph_from_config_edges
28
+ reads: file
29
+ in:
30
+ - config
31
+ - module_config
32
+ match:
33
+ file: paragraphs.paragraphs_type.*
34
+ filetype: yaml
35
+ id:
36
+ from: file_stem
37
+ normalize:
38
+ - {replace: '^paragraphs\.paragraphs_type\.', with: 'paragraph.'}
39
+ emits:
40
+ - edge:
41
+ kind: configured_by
42
+ from: this_node
43
+ to:
44
+ from:
45
+ key: id
46
+ template: 'paragraphs.paragraphs_type.{id}'
47
+ - edge:
48
+ kind: bundle_of
49
+ from: this_node
50
+ to:
51
+ from:
52
+ key: id
53
+ template: 'paragraph'
54
+ confidence: declared
@@ -0,0 +1,12 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-manifest.schema.json"
2
+
3
+ # The Paragraphs contributed module: each paragraph type, from its config file, as the bundle
4
+ # paragraph.<id> with its label, a configured_by edge to that file and a bundle_of edge to the
5
+ # entity type paragraph.
6
+ #
7
+ # Known gaps: a paragraph type's behavior plugins, icon and description give nothing. The entity
8
+ # type paragraph is declared by the module's PHP, which is not mapped, so it stays referenced. A
9
+ # field's allowed paragraph types give no edge.
10
+ pack: paragraphs_basic
11
+ version: 0.0.1
12
+ depends: [drupal_basic]