Collect and generate mapping from file-based routers

Overview

roullector: route collector

npm.badge codecov.badge bundlephobia.badge semantic-release.badge MIT

actions.ci.badge actions.release.badge actions.field.sveltekit.badge

tweet

Collect and generate route data from a file-based router such as svelte-kit's

What this does: show / hide
<!-- before -->
<script lang="ts">
  import { goto } from '$app/navigation';

  goto('/organiztion/org-abc/members/member-123/posts/prefix-too-much-literals-no-safety');
  // => 404 because organiztion is a typo
</script>

<!-- after -->
<script lang="ts">
  import { goto } from '$app/navigation';
  import { AppRoutes, route } from '$generated/routing';

  goto(
    route(
      AppRoutes.organization.$orgId.members.$memberId.posts.prefix$slug,
      'org-abc',
      'member-123',
      'type-support-no-typo',
    ),
  );
</script>

Table of Contents

Show / hide

Installation

npm install -D roullector
yarn add -D roullector
pnpm install -D roullector

Usage

This package was initially built and tested for svelte-kit. But I expect it to work in other cases using the configurable options. Examples used in this docs will use svelte-kit common route setup.

Quick Start

If you are using svelte-kit and want a no lock-in jump start, do, at project root,...

npx roullector collect

...and inspect the src/generated/routing directory for the generated goodies.

Example

If you have a directory that contains some routes like below...

directory: show / hide
src/routes/
  ├── __components/
  |       ├── Navbar.svelte
  |       └── Footer.svelte
  ├── __layout.svelte
  ├── __error.svelte
  ├── me.svelte
  ├── sign-in.svelte
  ├── sign-up.svelte
  ├── index.svelte
  └── admin/
      ├── __components/
      |     ├── Admin.layout.svelte
      |     ├── types.ts
      └── users/
          ├── [id]/
          |     ├── __layout.svelte
          |     ├── index.svelte
          |     ├── types.ts
          |     └── posts/
          |           ├── [post_id].svelte
          |           ├── s-[slug].svelte
          |           └── l-[short-link]-l.svelte
          └── index.svelte

...and a npm script that run roullector with default options,...

package.json: show/hide
// package.json
{
  "scripts": {
    "codegen:routing": "roullector collect"
  }
}

...the following files will be generated:

Generated: show / hide
// src/generated/routing/routes.json
{
  "admin": {
    "users": {
      "$id": {
        "index": "/admin/users/[id]",
        "posts": {
          "$postId": "/admin/users/[id]/posts/[post_id]",
          "l$shortLink$L": "/admin/users/[id]/posts/l-[short-link]-l",
          "s$slug": "/admin/users/[id]/posts/s-[slug]",
          "__dir": "/admin/users/[id]/posts"
        }
      },
      "index": "/admin/users"
    },
    "__dir": "/admin"
  },
  "index": "/",
  "me": "/me",
  "signIn": "/sign-in",
  "signUp": "/sign-up"
}
// src/generated/routing/index.ts
export { default as AppRoutes } from './routes.json';
/**
 * build a complete path with injected arguments
 * @param path {string} based path
 * @param args {string[]} arguments to inject
 */
export function route(path: string, ...args: string[]): string {
  const params = path.match(/\[[a-zA-Z_-]+\]/g) ?? [];
  for (const i in params) {
    path = path.replace(params[i], args[i]);
  }
  return path;
}

Notice that index.ts will import json, you need to configure your tsconfig.json to enable resolveJsonModule:

tsconfig.json: show / hide
// tsconfig.json
{
  "compilerOptions": {
    "resolveJsonModule": true
  }
}

You can then use the route helper to construct a complete path with typescript support built-in. For example:

path contruct: show / hide
import { AppRoutes } from '$generated/routing'; // or use relative path

const path = route(AppRoutes.admin.users.$id.posts.s$slug, 'user-id-123', 'slug');
// path = '/admin/users/user-id-123/posts/s-slug'

// ... later
// navigate(path);

Options

Run npx roullector collect help to for configurable options in command-line mode

Table of Options
name default description cli equivalent
inDir 'src/routes' input directory path to collect route data from -i, --inDir
extensions ['.svelte'] file extensions to accept -e, --extensions (comma-separated)
ignorePatterns [/^_/] patterns to ignore filenames -x, --ignorePatterns (comma-separated)
output true write generated files to disk?, if false will print to console --no-output
outDir 'src/generated/routing' output directory -o, --outDir
depth Infinity depth of directory traversal -d, --depth
dirkey __dir key to save path for directories with no index file -k, --dirkey
keyTransform [dollarArgify(), camelCasify()] how to transform route key in mapping -t, --keyTransform (allows multiple)
utils true generate utils for building path? --no-utils
typescript true generate files in typescript? --no-typescript
verbose false print more info during operation (for cli only) --verbose

Notes:

  • in command-line mode, keyTransform
    • only accepts these choices: dollarArg | camelCase | none,
    • if you want to specify multiple transforms, provide multiple arguments: --keyTransform=dollarArg --keyTransform=camelCase. The transforms will be applied in the order they are provided.
    • The rationale for the current default is to enable reference to the mapping without having to do something like AppRoutes['a-kebab-case']['[id'].
    • To opt out completely, do --keyTransform=none.
    • See implementation for more details.
  • for boolean options (default to true), the cli equivalent is --no-<option>, meaning only add the flag if you want to negate the option.

Library Usage

show / hide
import {
  collect,
  defaultCollectOptions,
  camelCasify,
  dollarArgify,
  compose,
} from `roullector`;

console.log('These are default options:', defaultCollectOptions);

let { json, route } = collect(); // use default options
// json = './src/generated/routing/routes.json'
// route = './src/generated/routing/index.ts'

({ json, route } = collect({ output: false; }); // helpful for testing
// json = generated route mapping content
// route = generated index source

const transformers = [dollarArgify, camelCasify];
({ json, route } = collect({
  keyTransform: [
    (key, original) => compose(key, ...defaultTransformers),
    // key = the current key in the transformation pipeline
    // original = the original key before all transformation
  ],
}))

Contributing

Read Contribution Guide


tweet

buy vnphanquang a coffee

You might also like...

A quickstart AWS Lambda function code generator. Downloads a template function code file, test harness file, sample SAM deffiniation and appropriate file structure.

Welcome to function-stencil 👋 A quickstart AWS Lambda function code generator. Downloads a template function code file, test harness file, sample SAM

Jun 20, 2022

Serve file server with single zip file as file system in Deno.

zipland Serve file server with one-single zip file in Deno. Support zip just zip32 with deflated or uncompressed serving plaintext deflate Examples Yo

Nov 2, 2022

Feel free to create new file, don't hesitate to pull your code, the most important thing is that the file name here must match your nickname so that file does not conflict with other people.

Hacktoberfest Indonesia Apa Itu Hacktoberfest ? Hacktoberfest adalah acara tahunan yang bertujuan untuk mendorong berkontribusi kedalam ekosistem open

Dec 15, 2022

A GitHub action to generate a stackaid.json file based on your repository's dependency graph

generate-stackaid-json A GitHub action to generate a stackaid.json file based on your repository's dependency graph This action is primarily intended

Sep 15, 2022

An application where a user can search a location by name and specify a genre of music. Based on the parameters entered, a list of radio stations generate based on genre selected in that area.

Signs of the Times Description An application that allows for the user to enter a date and see the horoscope for that day, and famous people born on t

Nov 3, 2022

Generate deterministic fake values: The same input will always generate the same fake-output.

Generate deterministic fake values: The same input will always generate the same fake-output.

import { copycat } from '@snaplet/copycat' copycat.email('foo') // = '[email protected]' copycat.email('bar') // = 'Thurman.Schowalter668@

Dec 30, 2022

Generate fluid, custom property based design systems on the fly — entirely based on Utopia

Fluid Design Systems With Netlify On-demand Builders A proof of concept demonstrating how Netlify on-demand builders can help generate fluid, custom p

Jan 5, 2023

A simple npm script to generate an .editorconfig file.

Create EditorConfig A simple npm script to generate an .editorconfig file. You don't know EditorConfig? Check out the official documentation! Usage Si

Dec 7, 2022

esbuild plugin to generate mix-manifest.json file compatible with Laravel Mix.

esbuild-mix-manifest-plugin An esbuild plugin to generate a mix-manifest.json compatible with Laravel Mix. Installation You can install the plugin via

Dec 25, 2022
Comments
  • fix: better parsing and tests

    fix: better parsing and tests

    • chore: format with prettier root config js files
    • test: unit test all transformers
    • test: unit test all parsers
    • fix(collect): better cli default arg message & correct default cli transformer order
    • docs: typo & better docs for keyTransform
    released 
    opened by vnphanquang 2
Releases(v1.1.2)
Owner
Quang Phan
Lifelong Learner. Problem Solver. Developer
Quang Phan
Prisma 2+ generator to emit fully implemented tRPC routers

Prisma tRPC Generator Automatically generate fully implemented tRPC routers from your Prisma Schema. This includes routers, app router and of course a

Omar Dulaimi 370 Jan 3, 2023
NoExGen is a node.js express application generator with modern folder structure, namespace/project mapping and much more! It contains preconfigured Settings and Routing files, ready to be used in any project.

Installation $ npm install -g noexgen Quick Start You can use Node Package Execution to create your node-express application as shown below: Create th

Souvik Sen 7 Oct 8, 2022
PEARL (Planetary Computer Land Cover Mapping) Platform API and Infrastructure

PEARL API & Infrastructure PEARL is a landcover mapping platform that uses human in the loop machine learning approach. This repository contains the A

Development Seed 47 Dec 23, 2022
🌬️ Server to collect and send air quality data.

Air Quality Measurement ??️ Server to collect and send air quality data. ?? Table of Contents About How it works Usage Getting Started Built Using Aut

Jean Poffo 5 Oct 12, 2022
Github action to collect metrics (CPU, memory, I/O, etc ...) from your workflows to help you debug and optimize your CI/CD pipeline

workflow-telemetry-action A GitHub Action to track and monitor the resource metrics of your GitHub Action workflow runs. If the run is triggered via a

Thundra 32 Dec 30, 2022
A example vault to collect and showcase various dataview queries. Created on behalf of AB1908

Obsidian Example Vault for Dataview Queries Good day! This example vault showcases different usages of the Dataview plugin for Obsidian.md. You'll fin

s-blu 184 Jan 5, 2023
Buildable's core open-source offering for actions that makes it easy to collect, centralize and action your backend system activity

What are Action Templates? Action Templates are open-source functions that save developers hundreds of hours when integrating databases, apps and othe

Buildable 6 Nov 5, 2022
Collect commonly used toolsets.

tool-helper English | 中文 Introduction Collect and organize commonly used tool functions to facilitate unified maintenance and management. It can also

Archer 4 Nov 26, 2022
Userland module that implements the module path mapping that Node.js does with "exports" in package.json

exports-map Userland module that implements the module path mapping that Node.js does with "exports" in package.json npm install exports-map Usage co

Mathias Buus 9 May 31, 2022
🐷 Collect historical performance data on your products via Lighthouse CI & Github Actions

Datahog ?? Datahog is a template repo, configured to collect historical performance data on your products via Lighhouse CI & Github Actions. Setup Cli

Jacob Størdahl 5 Sep 21, 2022