Skip to content

Getting started ​

Install ​

sh
npm i generated-signature
sh
pnpm add generated-signature
sh
yarn add generated-signature

TIP

generated-signature requires Node.js 24 or later, and is ESM only. From CommonJS, load it with a dynamic import: const { verify } = await import('generated-signature');.

Using populate-files? It signs and merges for you with signed: true. You only need this package's manualSection(), and the ESLint rule.

Sign a file ​

sign() adds a signature line at the top, in the file's comment syntax:

ts
import { 
sign
} from 'generated-signature';
const
text
=
sign
("export const version = '1.2.3';\n", {
filePath
: 'version.ts' });
ts
// @generated-signature v1:… Generated file. Do not edit outside of manual sections.
export const 
version
= '1.2.3';

The hash covers everything else in the file. Pass message to change the text after the token, or comment instead of filePath to give the comment syntax yourself:

ts
import { 
sign
} from 'generated-signature';
sign
('name = "x"\n', {
comment
: {
start
: '#' },
message
: 'Generated by my-tool.' });

Signing is idempotent, and keeps \r\n line breaks.

Add manual sections ​

A manual section is a region a person may edit. Render it with manualSection():

ts
import { 
manualSection
,
sign
} from 'generated-signature';
const
filePath
= 'client.ts';
const
generated
= `export class Client {
${
manualSection
({
id
: 'methods',
indent
: ' ',
filePath
,
body
: '// Add your own methods here' })}
} `; const
text
=
sign
(
generated
, {
filePath
});
ts
// @generated-signature v1:… Generated file. Do not edit outside of manual sections.
export class 
Client
{
// @manual-start methods // Add your own methods here // @manual-end methods }

The content between the markers is left out of the hash, so editing it keeps the signature valid. The marker lines are hashed, so adding, removing or renaming a section is an edit.

Regenerate ​

When writing over an existing file, verify it first, then carry its manual sections into the new output with mergeSections(), and sign the result:

ts
if (
verify
(
existing
).
status
!== 'valid') {
throw new
Error
('Edited by hand, not overwriting it');
} const {
text
,
orphans
} =
mergeSections
({
generated
,
existing
});
if (
orphans
.
length
> 0) {
throw new
Error
(`Manual sections would be lost: ${
orphans
.
join
(', ')}`);
} const
signed
=
sign
(
text
, {
filePath
: 'client.ts' });

Sections are matched by id. orphans lists sections that only the existing file has, and that someone wrote something in.

Verify ​

ts
const 
result
=
verify
(
text
);
const result: VerifyResult
statusMeaning
'valid'Signed, and unchanged outside manual sections.
'invalid'Signed, but changed outside manual sections.
'unsigned'No signature token.
'malformed'The token or markers can't be read. error says why, and on which line.

verify() never throws, so it is safe to run over any file. To check files while editing them, use the ESLint rule.

Next steps ​

  • ESLint: report hand-edited files in the editor and in lint.
  • File format: the token, markers, hash and manifest.
  • API reference: every function and error.