generated-signature 0.1.2 → 0.2.0
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.
- package/README.md +50 -41
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<div style="text-align:center">
|
|
2
2
|
|
|
3
3
|
# generated-signature
|
|
4
|
+
|
|
4
5
|
Sign generated files so hand edits are detected, while keeping manual sections editable.
|
|
5
6
|
|
|
6
7
|
[](https://www.npmjs.com/package/generated-signature)
|
|
@@ -101,15 +102,15 @@ export class AutoGenerated {
|
|
|
101
102
|
|
|
102
103
|
Fills in the signature token's hash, inserting a signature line first if the text has none.
|
|
103
104
|
|
|
104
|
-
| Parameter | Type
|
|
105
|
-
|
|
106
|
-
| `text`
|
|
105
|
+
| Parameter | Type | Description |
|
|
106
|
+
| --------- | -------- | -------------------------------------------------- |
|
|
107
|
+
| `text` | `string` | Required. Generated file content. |
|
|
107
108
|
| `options` | `object` | Required only when `text` has no token. See below. |
|
|
108
109
|
|
|
109
|
-
| Option
|
|
110
|
-
|
|
111
|
-
| `filePath` / `comment` | `string` / `CommentStyle` | —
|
|
112
|
-
| `message`
|
|
110
|
+
| Option | Type | Default | Description |
|
|
111
|
+
| ---------------------- | ------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
112
|
+
| `filePath` / `comment` | `string` / `CommentStyle` | — | Required. Comment syntax for the inserted line, either looked up from a file name (see [`commentStyle`](#commentstylefilepath)) or given directly. |
|
|
113
|
+
| `message` | `string` | `'Generated file. Do not edit outside of manual sections.'` | Text after the token on the inserted line. |
|
|
113
114
|
|
|
114
115
|
**Returns** `string`: the signed text. Signing is idempotent, and preserves `\r\n` line breaks.
|
|
115
116
|
|
|
@@ -133,11 +134,11 @@ Checks the file's signature.
|
|
|
133
134
|
|
|
134
135
|
**Returns** `VerifyResult`, discriminated on `status`:
|
|
135
136
|
|
|
136
|
-
| `status`
|
|
137
|
-
|
|
138
|
-
| `'valid'`
|
|
139
|
-
| `'invalid'`
|
|
140
|
-
| `'unsigned'`
|
|
137
|
+
| `status` | Meaning |
|
|
138
|
+
| ------------- | ------------------------------------------------------------------------------- |
|
|
139
|
+
| `'valid'` | Signed, and unchanged outside manual sections. |
|
|
140
|
+
| `'invalid'` | Signed, but changed outside manual sections. |
|
|
141
|
+
| `'unsigned'` | No signature token. |
|
|
141
142
|
| `'malformed'` | Has an `error: GeneratedSignatureMalformedError` explaining what can't be read. |
|
|
142
143
|
|
|
143
144
|
Never throws for any input string.
|
|
@@ -148,12 +149,12 @@ Never throws for any input string.
|
|
|
148
149
|
|
|
149
150
|
Renders a manual section for a generator to embed.
|
|
150
151
|
|
|
151
|
-
| Property
|
|
152
|
-
|
|
153
|
-
| `id`
|
|
154
|
-
| `body`
|
|
155
|
-
| `indent`
|
|
156
|
-
| `filePath` / `comment` |
|
|
152
|
+
| Property | Type | Default | Description |
|
|
153
|
+
| ---------------------- | -------- | ------- | -------------------------------------------------------------------------- |
|
|
154
|
+
| `id` | `string` | — | Required. Section id. |
|
|
155
|
+
| `body` | `string` | `''` | Default content, until someone edits it. A trailing line break is ignored. |
|
|
156
|
+
| `indent` | `string` | `''` | Prefixed to both markers and every non-blank body line. |
|
|
157
|
+
| `filePath` / `comment` | | — | Required. Comment syntax, as for [`sign`](#signtext-options). |
|
|
157
158
|
|
|
158
159
|
**Returns** `string`: the start marker, body and end marker lines, without a trailing line break.
|
|
159
160
|
|
|
@@ -165,10 +166,10 @@ Renders a manual section for a generator to embed.
|
|
|
165
166
|
|
|
166
167
|
Carries manual sections from an existing file into freshly generated text, matched by id.
|
|
167
168
|
|
|
168
|
-
| Property
|
|
169
|
-
|
|
169
|
+
| Property | Type | Description |
|
|
170
|
+
| ----------- | -------- | ------------------------------------------------------------ |
|
|
170
171
|
| `generated` | `string` | Required. New generator output, with default section bodies. |
|
|
171
|
-
| `existing`
|
|
172
|
+
| `existing` | `string` | Required. Current file content. |
|
|
172
173
|
|
|
173
174
|
**Returns** `{ text: string, orphans: readonly string[] }`. `text` is `generated` with each section's body taken from `existing` when it has the same id. `orphans` lists ids that only `existing` has and whose body isn't blank: dropping them would lose someone's edits, so callers should usually fail on them.
|
|
174
175
|
|
|
@@ -186,7 +187,15 @@ Carries manual sections from an existing file into freshly generated text, match
|
|
|
186
187
|
|
|
187
188
|
### `commentStyle(filePath)`
|
|
188
189
|
|
|
189
|
-
**Returns** the line comment syntax for a file, as `CommentStyle` (`{ start: string, end?: string }`), looked up by extension or file name (`Dockerfile`, `.gitignore`, …). `null` if unknown, or for formats without comments like `.json`.
|
|
190
|
+
**Returns** the line comment syntax for a file, as `CommentStyle` (`{ start: string, end?: string }`), looked up by extension or file name (`Dockerfile`, `.gitignore`, …). `null` if unknown, or for formats without comments like `.json`. For any other file, pass `comment` instead of `filePath`.
|
|
191
|
+
|
|
192
|
+
| `CommentStyle` | Files |
|
|
193
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
194
|
+
| `//` | `.c`, `.cc`, `.cjs`, `.cpp`, `.cs`, `.cts`, `.go`, `.h`, `.hpp`, `.java`, `.js`, `.json5`, `.jsonc`, `.jsx`, `.kt`, `.less`, `.mjs`, `.mts`, `.rs`, `.scss`, `.swift`, `.ts`, `.tsx` |
|
|
195
|
+
| `#` | `.bash`, `.cfg`, `.conf`, `.env`, `.ini`, `.pl`, `.properties`, `.py`, `.r`, `.rb`, `.sh`, `.toml`, `.yaml`, `.yml`, `.zsh`, and `.gitattributes`, `.gitignore`, `.npmignore`, `Dockerfile`, `Makefile` |
|
|
196
|
+
| `/* */` | `.css` |
|
|
197
|
+
| `<!-- -->` | `.htm`, `.html`, `.md`, `.mdx`, `.svg`, `.vue`, `.xml` |
|
|
198
|
+
| `--` | `.hs`, `.lua`, `.sql` |
|
|
190
199
|
|
|
191
200
|
---
|
|
192
201
|
|
|
@@ -208,12 +217,12 @@ A JSON file recording generated files that don't carry their own token, e.g. JSO
|
|
|
208
217
|
- `hash` is the [`contentHash`](#contenthashcontent) of the file. `signature: "inline"` means the file carries its own token, which is checked instead.
|
|
209
218
|
- `inputs` is optional: hashes of what produced the file, written and checked by the generator. This package doesn't interpret it.
|
|
210
219
|
|
|
211
|
-
| Function
|
|
212
|
-
|
|
220
|
+
| Function | Description |
|
|
221
|
+
| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
213
222
|
| <a id="contenthashcontent"></a>`contentHash(content: string \| Uint8Array): string` | `v1:` and 32 hex characters of SHA-256. `\r\n` counts as `\n`, also in bytes. Manual sections are **not** excluded, so a file with manual sections should be signed inline. |
|
|
214
|
-
| `verifyManifestEntry(content, entry): VerifyResult`
|
|
215
|
-
| `parseManifest(text): Manifest`
|
|
216
|
-
| `serializeManifest(files): string`
|
|
223
|
+
| `verifyManifestEntry(content: string \| Uint8Array, entry): VerifyResult` | `valid` or `invalid` for a `hash` entry; [`verify()`](#verifytext)'s result for an `inline` entry. |
|
|
224
|
+
| `parseManifest(text): Manifest` | Parses and validates. Throws `GeneratedSignatureManifestError` if the text is not a valid manifest. |
|
|
225
|
+
| `serializeManifest(files): string` | Manifest text, with paths and inputs sorted so the output doesn't depend on write order. |
|
|
217
226
|
|
|
218
227
|
---
|
|
219
228
|
|
|
@@ -221,12 +230,12 @@ A JSON file recording generated files that don't carry their own token, e.g. JSO
|
|
|
221
230
|
|
|
222
231
|
All errors extend the abstract `GeneratedSignatureError`.
|
|
223
232
|
|
|
224
|
-
| Error
|
|
225
|
-
|
|
226
|
-
| `GeneratedSignatureMalformedError`
|
|
227
|
-
| `GeneratedSignatureCommentStyleError` | `filePath: string`
|
|
228
|
-
| `GeneratedSignatureSectionIdError`
|
|
229
|
-
| `GeneratedSignatureManifestError`
|
|
233
|
+
| Error | Properties | Thrown when |
|
|
234
|
+
| ------------------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
235
|
+
| `GeneratedSignatureMalformedError` | `reason: MalformedReason`, `line: number` | A token or manual section can't be interpreted. `reason` is one of `'duplicate-section'`, `'duplicate-signature'`, `'invalid-section-id'`, `'nested-section'`, `'unclosed-section'`, `'unopened-section'`, `'unsupported-version'`. |
|
|
236
|
+
| `GeneratedSignatureCommentStyleError` | `filePath: string` | No comment syntax is known for a file. |
|
|
237
|
+
| `GeneratedSignatureSectionIdError` | `id: string` | `manualSection()` gets an invalid id. |
|
|
238
|
+
| `GeneratedSignatureManifestError` | | `parseManifest()` gets text that is not a valid manifest. |
|
|
230
239
|
|
|
231
240
|
## ESLint rules
|
|
232
241
|
|
|
@@ -239,11 +248,11 @@ import generatedSignature from 'generated-signature/eslint';
|
|
|
239
248
|
export default [generatedSignature.configs.recommended];
|
|
240
249
|
```
|
|
241
250
|
|
|
242
|
-
`configs.recommended` registers the plugin (namespace `generated-signature`) and turns on every rule below as an error.
|
|
251
|
+
`configs.recommended` registers the plugin (namespace `generated-signature`) and turns on every rule below as an error. `eslint` is an optional peer dependency (`^10.13.0`), needed only for this entry point. To choose rules yourself, register the plugin: `{ plugins: { 'generated-signature': generatedSignature }, rules: { 'generated-signature/valid': 'warn' } }`.
|
|
243
252
|
|
|
244
253
|
### `generated-signature/valid`
|
|
245
254
|
|
|
246
|
-
Reports a file whose signature doesn't match (it was edited outside its manual sections), or whose token or manual sections are malformed. Unsigned files are ignored. There is no autofix: re-signing would just approve the edit. Regenerate the file instead, or move the change into a manual section.
|
|
255
|
+
Reports a file whose signature doesn't match (it was edited outside its manual sections; reported on the token), or whose token or manual sections are malformed (`Generated file is malformed: <reason>`, reported on the line at fault). Unsigned files are ignored. There is no autofix: re-signing would just approve the edit. Regenerate the file instead, or move the change into a manual section.
|
|
247
256
|
|
|
248
257
|
```ts
|
|
249
258
|
// @generated-signature v1:… Generated file. Do not edit outside of manual sections.
|
|
@@ -257,12 +266,12 @@ ESLint only lints the files it is configured for. To check every signed file wha
|
|
|
257
266
|
|
|
258
267
|
## Compared to alternatives
|
|
259
268
|
|
|
260
|
-
|
|
|
261
|
-
|
|
262
|
-
| `generated-signature`
|
|
263
|
-
| Meta's SignedSource / `@partially-generated`
|
|
264
|
-
| [cog](https://nedbatchelder.com/code/cog/) `--checksum` | Yes
|
|
265
|
-
| Go's `// Code generated ... DO NOT EDIT.`
|
|
269
|
+
| | Signature | Manual sections | Language |
|
|
270
|
+
| ------------------------------------------------------- | --------------------- | ------------------------------------------------ | ------------------------------------------------ |
|
|
271
|
+
| `generated-signature` | Yes | Yes | Any text format, JS API |
|
|
272
|
+
| Meta's SignedSource / `@partially-generated` | Yes | Yes | Internal tooling, Hack/JS, not a general library |
|
|
273
|
+
| [cog](https://nedbatchelder.com/code/cog/) `--checksum` | Yes | Inverse: generated regions in a handwritten file | Python |
|
|
274
|
+
| Go's `// Code generated ... DO NOT EDIT.` | No, a convention only | No | Go |
|
|
266
275
|
|
|
267
276
|
## Also See
|
|
268
277
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "generated-signature",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Sign generated files so hand edits are detected, while keeping manual sections editable",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Sign generated files so hand edits are detected, while keeping manual sections editable.",
|
|
5
5
|
"engines": {
|
|
6
|
-
"node": ">=
|
|
6
|
+
"node": ">=22.13.0"
|
|
7
7
|
},
|
|
8
8
|
"type": "module",
|
|
9
9
|
"author": "JacobLey",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"url": "git+https://github.com/JacobLey/leyman.git",
|
|
14
14
|
"directory": "tools/generated-signature/generated-signature"
|
|
15
15
|
},
|
|
16
|
-
"homepage": "https://github.
|
|
16
|
+
"homepage": "https://jacobley.github.io/leyman/packages/generated-signature/",
|
|
17
17
|
"bugs": {
|
|
18
18
|
"url": "https://github.com/JacobLey/leyman/issues"
|
|
19
19
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"!dist/tsconfig.tsbuildinfo"
|
|
37
37
|
],
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"eslint": "^10.
|
|
39
|
+
"eslint": "^10.13.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependenciesMeta": {
|
|
42
42
|
"eslint": {
|
|
@@ -44,19 +44,19 @@
|
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@biomejs/biome": "^2.
|
|
47
|
+
"@biomejs/biome": "^2.6.4",
|
|
48
48
|
"@leyman/eslint-config": "^0.0.1",
|
|
49
49
|
"@leyman/expect": "^0.0.1",
|
|
50
50
|
"@swc/cli": "^0.8.1",
|
|
51
|
-
"@swc/core": "^1.16.
|
|
51
|
+
"@swc/core": "^1.16.20",
|
|
52
52
|
"@types/mocha": "^10.0.10",
|
|
53
|
-
"@types/node": "^
|
|
53
|
+
"@types/node": "^22.20.5",
|
|
54
54
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
55
55
|
"c8": "^12.0.0",
|
|
56
|
-
"eslint": "^10.
|
|
56
|
+
"eslint": "^10.13.0",
|
|
57
57
|
"expect-type": "^1.4.0",
|
|
58
|
-
"mocha": "^12.0.
|
|
59
|
-
"mocha-chain": "^1.0
|
|
58
|
+
"mocha": "^12.0.3",
|
|
59
|
+
"mocha-chain": "^1.1.0",
|
|
60
60
|
"typescript": "npm:@typescript/typescript6@^6.0.2"
|
|
61
61
|
},
|
|
62
62
|
"imports": {
|