npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

make-me-a-content

v0.3.0

Published

[![npm version](https://badge.fury.io/js/make-me-a-content.svg)](https://badge.fury.io/js/make-me-a-content) [![install size](https://packagephobia.now.sh/badge?p=make-me-a-content)](https://packagephobia.now.sh/result?p=make-me-a-content) [![Coverage Sta

Downloads

125

Readme

make-me-a-content

npm version install size Coverage Status

mmac allows you to have templated sections in your source code and documentation.

It is heavily inspired by how Rome generates docs and source code.

Installation

npm install -D make-me-a-content

Example

Let's take a look at a file where there can be a large amount of templated content. The imports and the exported object are extremely repetitive. It makes sense to generate this section to avoid human error.

/* GENERATED_START(id:main;hash:sldkjflj425l26k45nl2kn54k6b2) This is generated content, do not modify by hand, to regenerate run "npm run build-docs" */
import bar from './things/bar.js'
import foo from './things/foo.js'

export const certainItems = {
    [bar.name]: bar,
    [foo.name]: foo,
}
/* GENERATED_END(id:main) */

Also the documentation where the same items need to be referenced.

Readme content

<!-- GENERATED_START(id:main;hash:sldkjflj425l26k45nl2kn54k6b2) This is generated content, do not modify by hand, to regenerate run "npm run build-docs" -->
| title          | description              | default value |
| :------------- | :----------------------: | ------------: |
|  Bar           | why you should use bar   |  default val  |
|  Foo           | why you should use foo   |  default val  |
<!-- GENERATED_END(id:main) -->

More content

Generation script

// scripts/update-docs.js

import fs from 'fs'
import path from 'path'
import {mmac} from 'make-me-a-content'

async function updateScripts() {
    const thingsDirContents = await fs.promises.readdir('./path/to/things') // ['foo.js', 'bar.js']

    // --- Source code
    const newSourceCodeContent = [
        ...thingsDirContents.map(
            filename => `import ${path.parse(filename).name} from './${filename}'`
        ),
        '', // to have an empty line in the output
        `const certainItems = {`
        ...thingsDirContents.map(
            filename => `    [${path.parse(filename).name}.name]: ${path.parse(filename).name}},`
        ),
        `}`
    ]

    await mmac({
        filepath: './path/to/somefile.js',
        lines: newSourceCodeContent,
        updateScript: 'npm run update-docs',
    })

    // --- Documentation
    const modules = await thingsDirContents.map(filename => import(`./path/to/things/${filename}`))
    const newDocsContent = [
        '| title          | description              | default value |',
        '| :------------- | :----------------------: | ------------: |',
        ...modules.map(m => `| ${m.name} | ${m.description} | ${m.defaultValue} |`)
    ]

    await mmac({
        filepath: './path/to/README.md',
        lines: newDocsContent,
        updateScript: 'npm run update-docs',
    })
}

updateScripts()

package.json

{
    "name": "your project",
    "scripts": {
        "update-docs": "node ./scripts/update-docs",
        "start": "node ./src/index.js"
    }
}

Usage

import {mmac} from 'make-me-a-content'

mmac({
    updateScript: 'npm run update-docs',
    filepath: './path/to/file.ext',
    lines: ['new content', 'to be inserted', 'between', 'marks']
})

Options

  • filepath path to a file to be updated
  • updateScript script to be run in your project to regenerate this section
  • lines content to be put between the marks
  • id to be user in content marks, optional, default is main
  • hash to be used in start mark, optional, default is md5 hash generated from the lines
  • comments add new comments by a file extension or overwrite existing ones
  • transform modify the new file content

Check for unstaged files

If you think of generating content for your project, you probably want to make sure that the content is always up to date. You can do this by calling mmac-check in a precommit and/or a CI check. You should call it directly after your content generation scripts. The script in your package.json should look similar to below.

{
    "name": "project-name",
    "scripts": {
        "generate-content": "node ./scripts/update-docs.js && mmac-check",
    }
}

Alternatively you can check for unstaged files yourself using a provided checkUnstaged function.

import {mmac, checkUnstaged} from 'make-me-a-content'

function main() {
    const updateScript = 'npm run generate-content'

    mmac({updateScript, /* ... */})

    const files = checkUnstaged()

    if (files.length > 0) {
        console.log(`Unstaged files, run "${updateScript}" locally and commit the changes`)
        process.exit(1)
    }
}

FAQ

The very first generation

Make sure you have added the start and end marks to the file where you want to insert the content. Ie

/* GENERATED_START(id:main;hash) */
/* GENERATED_END(id:main) */

How to format or prettify the content?

If you wish to also prettify file using eslint/prettier or another tool, you can use the transform option.

import {mmac} from 'make-me-a-content'
import prettier from 'prettier'

mmac({
    updateScript: 'npm run update-docs',
    filepath: './path/to/file.ext',
    lines: ['new content'],
    transform: newContent => prettier.format(newContent, {/* prettier options */})
})

How to have multiple templated sections in a single file?

To do that you can provide a different id per each section. The default one is "main". Example:

import {mmac} from 'make-me-a-content'

mmac({
    id: 'foo',
    updateScript: 'npm run update-docs',
    filepath: './path/to/file.ext',
    lines: ['foo content'],
})

mmac({
    id: 'bar',
    updateScript: 'npm run update-docs',
    filepath: './path/to/file.ext',
    lines: ['bar content'],
})

Why is updateScript not optional?

Having the comment about the content being generated and the script to update it lowers the learning curve for people seeing it for the first time.

Add or change comments for other file extensions

You can overwrite comments per file extension using the comments options

mmac({
    comments: {
        // overwrite javascript comments to use single line comment
        ".js": {
            start: "// ",
            end: "",
        },
        // support lua files
        ".lua": {
            start: "-- ",
            end: "",
        },
    },
    // other mmac options
})