@orkestrel/scaffold 0.0.86 → 0.0.88
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/dist/agents/skills/orkestrel-harden/scripts/discovery.js +9 -4
- package/dist/bin/main.js +3 -3
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/skills/orkestrel-harden/scripts/discovery.ts +12 -3
- package/dist/host/claude/agents/orkestrel.md +3 -3
- package/dist/host/claude/rules/architecture.md +19 -6
- package/dist/host/claude/rules/names.md +13 -11
- package/dist/host/configs/policy.ts +96 -27
- package/dist/host/dotfiles/oxlintrc.json +1 -0
- package/dist/host/guides/browser.md +2626 -1195
- package/dist/host/guides/contract.md +1 -1
- package/dist/host/guides/guide.md +13 -8
- package/dist/host/manifest.json +11 -11
- package/dist/host/tests/config.test.ts +176 -0
- package/dist/src/core/index.cjs +10 -3
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +7 -7
- package/dist/src/core/index.d.ts +7 -7
- package/dist/src/core/index.js +10 -3
- package/dist/src/core/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -97,9 +97,18 @@ function listCollected(config: string): readonly Collected[] | undefined {
|
|
|
97
97
|
maxBuffer: 64 * 1024 * 1024,
|
|
98
98
|
windowsHide: true,
|
|
99
99
|
})
|
|
100
|
-
if (result.status !== 0) return undefined
|
|
101
100
|
const start = result.stdout.indexOf('[')
|
|
102
|
-
if (start === -1)
|
|
101
|
+
if (result.status !== 0 || start === -1) {
|
|
102
|
+
const diagnostic = result.stderr || result.error?.message || result.stdout
|
|
103
|
+
console.error(
|
|
104
|
+
diagnostic
|
|
105
|
+
.split(/\r\n|\n/u)
|
|
106
|
+
.filter((line) => line.trim() !== '')
|
|
107
|
+
.slice(0, 12)
|
|
108
|
+
.join('\n'),
|
|
109
|
+
)
|
|
110
|
+
return undefined
|
|
111
|
+
}
|
|
103
112
|
const parsed: unknown = JSON.parse(result.stdout.slice(start))
|
|
104
113
|
if (!Array.isArray(parsed)) return undefined
|
|
105
114
|
const collected: Collected[] = []
|
|
@@ -151,7 +160,7 @@ function main(argv: readonly string[]): number {
|
|
|
151
160
|
const gates = readGates(readScripts())
|
|
152
161
|
const collected = listCollected(config)
|
|
153
162
|
if (collected === undefined) {
|
|
154
|
-
console.error('discovery: vitest list failed
|
|
163
|
+
console.error('discovery: vitest list failed')
|
|
155
164
|
return 2
|
|
156
165
|
}
|
|
157
166
|
const named = (readOption(argv, '--projects') ?? '').split(',').filter((name) => name !== '')
|
|
@@ -48,7 +48,7 @@ so network-controlled descriptions never enter agent instruction context.
|
|
|
48
48
|
| `@orkestrel/abort` | `0.0.12` | L1 | `@orkestrel/contract` `^0.0.18` | |
|
|
49
49
|
| `@orkestrel/agent` | `0.0.25` | L5 | `@orkestrel/tool` `^0.0.17`, `@orkestrel/abort` `^0.0.12`, `@orkestrel/queue` `^0.0.15`, `@orkestrel/budget` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/timeout` `^0.0.12`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/database` `^0.0.16`, `@orkestrel/workflow` `^0.0.20`, `@orkestrel/workspace` `^0.0.10` | |
|
|
50
50
|
| `@orkestrel/brief` | `0.0.10` | L4 | `@orkestrel/reason` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/interpret` `^0.0.15` | |
|
|
51
|
-
| `@orkestrel/browser` | `0.0.
|
|
51
|
+
| `@orkestrel/browser` | `0.0.21` | L5 | `@orkestrel/mcp` `^0.0.35`, `@orkestrel/html` `^0.0.12`, `@orkestrel/tool` `^0.0.18`, `@orkestrel/router` `^0.0.16`, `@orkestrel/server` `^0.0.22`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/markdown` `^0.0.17`, `@orkestrel/websocket` `^0.0.14` | |
|
|
52
52
|
| `@orkestrel/budget` | `0.0.12` | L1 | `@orkestrel/contract` `^0.0.18` | |
|
|
53
53
|
| `@orkestrel/codec` | `0.0.5` | L1 | `@orkestrel/contract` `^0.0.18` | |
|
|
54
54
|
| `@orkestrel/console` | `0.0.15` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
|
|
@@ -57,7 +57,7 @@ so network-controlled descriptions never enter agent instruction context.
|
|
|
57
57
|
| `@orkestrel/database` | `0.0.16` | L2 | `@orkestrel/sqlite` `^0.0.13`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/indexeddb` `^0.0.13` | |
|
|
58
58
|
| `@orkestrel/emitter` | `0.0.11` | L1 | `@orkestrel/contract` `^0.0.18` | |
|
|
59
59
|
| `@orkestrel/form` | `0.0.8` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
|
|
60
|
-
| `@orkestrel/guide` | `0.0.
|
|
60
|
+
| `@orkestrel/guide` | `0.0.24` | L3 | `@orkestrel/contract` `^0.0.19`, `@orkestrel/markdown` `^0.0.17` | |
|
|
61
61
|
| `@orkestrel/html` | `0.0.12` | L1 | `@orkestrel/contract` `^0.0.19` | |
|
|
62
62
|
| `@orkestrel/indexeddb` | `0.0.13` | L1 | `@orkestrel/contract` `^0.0.18` | |
|
|
63
63
|
| `@orkestrel/interpret` | `0.0.15` | L3 | `@orkestrel/reason` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/template` `^0.0.9` | |
|
|
@@ -78,7 +78,7 @@ so network-controlled descriptions never enter agent instruction context.
|
|
|
78
78
|
| `@orkestrel/reason` | `0.0.12` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
|
|
79
79
|
| `@orkestrel/relation` | `0.0.14` | L3 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/database` `^0.0.16` | |
|
|
80
80
|
| `@orkestrel/router` | `0.0.16` | L2 | `@orkestrel/abort` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
|
|
81
|
-
| `@orkestrel/scaffold` | `0.0.
|
|
81
|
+
| `@orkestrel/scaffold` | `0.0.87` | L3 | `@orkestrel/console` `^0.0.15`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/process` `^0.0.14`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/markdown` `^0.0.17`, `@orkestrel/template` `^0.0.9` | |
|
|
82
82
|
| `@orkestrel/sea` | `0.0.18` | L3 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/process` `^0.0.14`, `@orkestrel/contract` `^0.0.18` | |
|
|
83
83
|
| `@orkestrel/server` | `0.0.22` | L3 | `@orkestrel/abort` `^0.0.12`, `@orkestrel/codec` `^0.0.5`, `@orkestrel/router` `^0.0.16`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/timeout` `^0.0.12`, `@orkestrel/contract` `^0.0.19` | |
|
|
84
84
|
| `@orkestrel/sqlite` | `0.0.13` | L1 | `@orkestrel/contract` `^0.0.18` | |
|
|
@@ -28,6 +28,7 @@ paths:
|
|
|
28
28
|
| Shape/algorithm compilers | `*/compilers.ts` |
|
|
29
29
|
| Entity/value factories | `*/factories.ts` |
|
|
30
30
|
| Middleware factories | `*/middlewares.ts` |
|
|
31
|
+
| Plugin factories | `*/plugins.ts` |
|
|
31
32
|
| Request handlers | `*/handlers.ts` |
|
|
32
33
|
| Route tables | `*/routes.ts` |
|
|
33
34
|
| Seeders | `*/seeders.ts` |
|
|
@@ -63,7 +64,8 @@ Use only the centralized files an environment needs.
|
|
|
63
64
|
- non-trivial or reusable → extract, export, unit-test, and route every duplicate through it.
|
|
64
65
|
- `factories.ts`, `compilers.ts`, and `parsers.ts` are centralized files, not hiding places. Factory glue extracts to `helpers.ts`; pure compiler/parser recursion remains exported in its own kind file.
|
|
65
66
|
- Every exported function in `parsers.ts` is named `parse*`. Every exported function in
|
|
66
|
-
`factories.ts` is named `create*`.
|
|
67
|
+
`factories.ts` is named `create*`. Every exported function in `plugins.ts` is named
|
|
68
|
+
`create{Entity}Plugin`, or `create{Name}Plugins` when it returns a collection.
|
|
67
69
|
- Those name forms are one-directional. A name does not place a function: `createWriteDirectory`
|
|
68
70
|
creates a directory rather than an entity and `isVacant` is a predicate rather than a `Guard<T>`,
|
|
69
71
|
so both stay in `helpers.ts`. Placement follows what the function is; the name form follows
|
|
@@ -86,7 +88,7 @@ Use only the centralized files an environment needs.
|
|
|
86
88
|
- Keep the leaf pair class-free. `helpers.ts` and `validators.ts` sit at the bottom of a module's
|
|
87
89
|
graph: they import types, constants, errors, and each other, and they import no implementation
|
|
88
90
|
class. Every file that constructs or drives a class — `cloners.ts`, `compilers.ts`, `factories.ts`,
|
|
89
|
-
`shapers.ts` — sits above them, consumes them, and is never consumed by them. One cycle between
|
|
91
|
+
`plugins.ts`, `shapers.ts` — sits above them, consumes them, and is never consumed by them. One cycle between
|
|
90
92
|
the leaves is the shape this produces and is acceptable; an edge running downward from a
|
|
91
93
|
class-importing file into the leaf pair is not.
|
|
92
94
|
- `templates.ts` and `contracts.ts` hold data only — shipped template definitions and compiled
|
|
@@ -126,11 +128,15 @@ neither reads meaning.
|
|
|
126
128
|
freeze obligation in the earlier kind-purity rules binds regardless; only the bare literal is
|
|
127
129
|
mechanical.
|
|
128
130
|
- The plugin does not tell one function kind from another. Every centralized file that permits
|
|
129
|
-
functions reads the same to it apart from the `parse
|
|
130
|
-
`combinators.ts`, `compilers.ts`, `errors.ts`, `factories.ts`, `handlers.ts`,
|
|
131
|
-
`
|
|
132
|
-
`shapers.ts`, and `validators.ts`. That list is exhaustive, a new function kind joins it, and no
|
|
131
|
+
functions reads the same to it apart from the `parse*`, `create*`, `create*Plugin`, and `create*Plugins` name
|
|
132
|
+
forms: `cloners.ts`, `combinators.ts`, `compilers.ts`, `errors.ts`, `factories.ts`, `handlers.ts`,
|
|
133
|
+
`helpers.ts`, `inferers.ts`, `middlewares.ts`, `parsers.ts`, `plugins.ts`, `relations.ts`,
|
|
134
|
+
`schemas.ts`, `seeders.ts`, `shapers.ts`, and `validators.ts`. That list is exhaustive, a new function kind joins it, and no
|
|
133
135
|
later version of the plugin claims more.
|
|
136
|
+
- The name forms read names only: a function, an export specifier, an exported import alias, and a
|
|
137
|
+
star re-export in the kind file. They never read a return type, so a `create{Name}Plugins` that
|
|
138
|
+
returns one plugin passes; review owns arity. A value binding in a kind file is the data rule's
|
|
139
|
+
finding, not the name form's.
|
|
134
140
|
- The plugin reports no `data` violation in `helpers.ts`. The kind rules place a camelCase
|
|
135
141
|
namespace of functions there, and a namespace of callables is not separable from a data table by
|
|
136
142
|
declaration syntax, so `DATA_EXEMPT_FILES` in `configs/policy.ts` excludes the file. Ordinary
|
|
@@ -202,6 +208,13 @@ Store child managers in `#` fields and expose readonly getters typed as their in
|
|
|
202
208
|
- Extract reusable cross-middleware machinery to helpers/classes.
|
|
203
209
|
- `MiddlewareManager` is the sole manager of the middleware composition chain; do not create one manager per middleware.
|
|
204
210
|
|
|
211
|
+
## Plugins
|
|
212
|
+
|
|
213
|
+
- A plugin is a value a host composes at creation: the binding of one entity class to the host's extension seam. The entity class stays unaware of it.
|
|
214
|
+
- Place plugin factories in `plugins.ts` as `create{Entity}Plugin(options?)`, and a factory of a host's collection as `create{Name}Plugins()`; keep them distinct from the entity factories in `factories.ts`.
|
|
215
|
+
- A plugin factory builds and returns the value; it never registers, installs, or boots anything. The host's creation options take the plugin list, and registration happens there.
|
|
216
|
+
- A plugin drives its entity through the entity's public interface. When the host needs behavior the interface lacks, add it to the interface as a real entity capability; never reach a private member from the plugin.
|
|
217
|
+
|
|
205
218
|
## Environment/module placement
|
|
206
219
|
|
|
207
220
|
- Shared cross-environment logic belongs in the central core/shared layer. Other environments import core; core imports neither browser nor server.
|
|
@@ -169,17 +169,18 @@ Keep canonical case:
|
|
|
169
169
|
|
|
170
170
|
## Value-level identifiers
|
|
171
171
|
|
|
172
|
-
| Kind | Required form
|
|
173
|
-
| -------------- |
|
|
174
|
-
| Class | PascalCase `{Entity}`
|
|
175
|
-
| Manager class | PascalCase `{Entity}Manager`
|
|
176
|
-
| Factory | camelCase `create{Entity}`
|
|
177
|
-
|
|
|
178
|
-
|
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
|
|
|
182
|
-
|
|
|
172
|
+
| Kind | Required form |
|
|
173
|
+
| -------------- | -------------------------------------------------------------------- |
|
|
174
|
+
| Class | PascalCase `{Entity}` |
|
|
175
|
+
| Manager class | PascalCase `{Entity}Manager` |
|
|
176
|
+
| Factory | camelCase `create{Entity}` |
|
|
177
|
+
| Plugin factory | camelCase `create{Entity}Plugin`; a collection `create{Name}Plugins` |
|
|
178
|
+
| Guard | camelCase `is{Condition}` |
|
|
179
|
+
| Helper | camelCase `{verb}{Noun}` |
|
|
180
|
+
| Constant | UPPER_SNAKE_CASE `{QUALIFIER}_{NOUN}` |
|
|
181
|
+
| Property/field | camelCase bare noun |
|
|
182
|
+
| Method | camelCase bare verb |
|
|
183
|
+
| Boolean | camelCase adjective/past participle |
|
|
183
184
|
|
|
184
185
|
## Fixed derivation/construction forms
|
|
185
186
|
|
|
@@ -187,6 +188,7 @@ Keep canonical case:
|
|
|
187
188
|
- `is*`: total `Guard<T>`; never throws; returns false off-shape.
|
|
188
189
|
- `parse*`: coercion producing `T | undefined`; cross-type conversion never belongs in a guard.
|
|
189
190
|
- `create*`: the factory form; `.claude/rules/architecture.md` § Kind purity states what a factory is and where it lives.
|
|
191
|
+
- `create*Plugin` and `create*Plugins`: the plugin-factory forms; `.claude/rules/architecture.md` § Plugins owns what a plugin is and what its factory does. Never name a plugin factory `register*` or `install*`.
|
|
190
192
|
- `*Of`: combinator named for its constituents, combining them into a container/guard/value, such as `arrayOf(guard)` or `boundsOf(min, max)`.
|
|
191
193
|
- `{noun}To{Noun}`: projection from a whole to a derived view, such as `definitionToSnapshot`.
|
|
192
194
|
- `*Shape`: `ContractShape` value/JSON-Schema blueprint, not a function or type.
|
|
@@ -31,6 +31,13 @@ export interface PolicyExpression extends PolicyNode {
|
|
|
31
31
|
readonly source?: PolicyExpression
|
|
32
32
|
readonly specifiers?: readonly PolicyExpression[]
|
|
33
33
|
readonly imported?: PolicyExpression
|
|
34
|
+
readonly exported?: PolicyExpression
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Pairs a name-form kind file's name pattern with the message id a misnamed export reports. */
|
|
38
|
+
export interface PolicyNameForm {
|
|
39
|
+
readonly pattern: RegExp
|
|
40
|
+
readonly messageId: string
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
/** Pairs one declared module function with the name a prefix rule reads. */
|
|
@@ -145,6 +152,7 @@ export const CENTRAL_SOURCE_FILES: readonly string[] = Object.freeze([
|
|
|
145
152
|
'inferers.ts',
|
|
146
153
|
'middlewares.ts',
|
|
147
154
|
'parsers.ts',
|
|
155
|
+
'plugins.ts',
|
|
148
156
|
'relations.ts',
|
|
149
157
|
'routes.ts',
|
|
150
158
|
'schemas.ts',
|
|
@@ -167,6 +175,7 @@ export const FUNCTION_SOURCE_FILES: readonly string[] = Object.freeze([
|
|
|
167
175
|
'inferers.ts',
|
|
168
176
|
'middlewares.ts',
|
|
169
177
|
'parsers.ts',
|
|
178
|
+
'plugins.ts',
|
|
170
179
|
'relations.ts',
|
|
171
180
|
'schemas.ts',
|
|
172
181
|
'seeders.ts',
|
|
@@ -274,6 +283,16 @@ export const POLICY_TAG_PATTERN = /\{@(?:linkcode|linkplain|link|inheritDoc)\b[^
|
|
|
274
283
|
/** Matches a URL, whose segments are an address rather than prose. */
|
|
275
284
|
export const POLICY_URL_PATTERN = /https?:\/\/\S+/gu
|
|
276
285
|
|
|
286
|
+
/** Maps each name-form kind file to the form every function it exports must take. */
|
|
287
|
+
export const POLICY_NAME_FORMS: Readonly<Record<string, PolicyNameForm>> = Object.freeze({
|
|
288
|
+
'parsers.ts': Object.freeze({ pattern: /^parse/u, messageId: 'parser' }),
|
|
289
|
+
'factories.ts': Object.freeze({ pattern: /^create/u, messageId: 'factory' }),
|
|
290
|
+
'plugins.ts': Object.freeze({
|
|
291
|
+
pattern: /^create[A-Z][A-Za-z0-9]*Plugins?$/u,
|
|
292
|
+
messageId: 'plugin',
|
|
293
|
+
}),
|
|
294
|
+
})
|
|
295
|
+
|
|
277
296
|
/**
|
|
278
297
|
* Lists the words ending in `s` that open a sentence without being a third-person verb.
|
|
279
298
|
*
|
|
@@ -992,24 +1011,44 @@ export function reportConstant(context: PolicyContext, node: PolicyExpression):
|
|
|
992
1011
|
}
|
|
993
1012
|
}
|
|
994
1013
|
|
|
995
|
-
/**
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1014
|
+
/**
|
|
1015
|
+
* Reports a function in the named kind file whose name breaks that file's form, an export specifier
|
|
1016
|
+
* or exported import alias there that publishes a name outside it, and a star re-export there, whose
|
|
1017
|
+
* names the form cannot read.
|
|
1018
|
+
*/
|
|
1019
|
+
export function reportName(context: PolicyContext, node: PolicyExpression, file: string): void {
|
|
1020
|
+
const form = POLICY_NAME_FORMS[file]
|
|
1021
|
+
if (form === undefined || pathToPolicyFile(context.filename) !== file) return
|
|
1022
|
+
if (node.type === 'ExportAllDeclaration') {
|
|
1023
|
+
context.report({ node, messageId: form.messageId })
|
|
1024
|
+
return
|
|
1025
|
+
}
|
|
1026
|
+
if (node.type === 'ExportNamedDeclaration') {
|
|
1027
|
+
const alias = node.declaration
|
|
1028
|
+
if (alias?.type === 'TSImportEqualsDeclaration') {
|
|
1029
|
+
const name = identifierToPolicyName(alias.id)
|
|
1030
|
+
if (name === undefined || !form.pattern.test(name)) {
|
|
1031
|
+
context.report({ node: alias, messageId: form.messageId })
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
for (const specifier of node.specifiers ?? []) {
|
|
1035
|
+
const exported = specifier.exported
|
|
1036
|
+
const name =
|
|
1037
|
+
typeof exported?.name === 'string'
|
|
1038
|
+
? exported.name
|
|
1039
|
+
: typeof exported?.value === 'string'
|
|
1040
|
+
? exported.value
|
|
1041
|
+
: undefined
|
|
1042
|
+
if (name === undefined || !form.pattern.test(name)) {
|
|
1043
|
+
context.report({ node: specifier, messageId: form.messageId })
|
|
1044
|
+
}
|
|
1002
1045
|
}
|
|
1046
|
+
return
|
|
1003
1047
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
/** Reports a factories.ts function whose name lacks the create prefix. */
|
|
1007
|
-
export function reportFactory(context: PolicyContext, node: PolicyExpression): void {
|
|
1008
|
-
if (isPolicyAmbient(context.filename) || !isPolicyTop(node)) return
|
|
1009
|
-
if (pathToPolicyFile(context.filename) !== 'factories.ts') return
|
|
1048
|
+
if (!isPolicyTop(node)) return
|
|
1010
1049
|
for (const binding of statementToPolicyBindings(node)) {
|
|
1011
|
-
if (binding.name === undefined || !binding.name
|
|
1012
|
-
context.report({ node: binding.node, messageId:
|
|
1050
|
+
if (binding.name === undefined || !form.pattern.test(binding.name)) {
|
|
1051
|
+
context.report({ node: binding.node, messageId: form.messageId })
|
|
1013
1052
|
}
|
|
1014
1053
|
}
|
|
1015
1054
|
}
|
|
@@ -1252,44 +1291,73 @@ export const CONSTANT_RULE: PolicyRuleInterface = {
|
|
|
1252
1291
|
},
|
|
1253
1292
|
}
|
|
1254
1293
|
|
|
1255
|
-
/** Bans a parsers.ts function whose name lacks the parse prefix. */
|
|
1294
|
+
/** Bans a parsers.ts function or export whose name lacks the parse prefix. */
|
|
1256
1295
|
export const PARSER_RULE: PolicyRuleInterface = {
|
|
1257
1296
|
meta: {
|
|
1258
1297
|
type: 'problem',
|
|
1259
1298
|
docs: {
|
|
1260
|
-
description: 'Disallow a parsers.ts function whose name does not start with parse.',
|
|
1299
|
+
description: 'Disallow a parsers.ts function or export whose name does not start with parse.',
|
|
1261
1300
|
},
|
|
1262
1301
|
messages: {
|
|
1263
1302
|
parser:
|
|
1264
|
-
'Name this parsers.ts function with the parse prefix, or move it to its own kind file.',
|
|
1303
|
+
'Name this parsers.ts function or export with the parse prefix, or move it to its own kind file.',
|
|
1265
1304
|
},
|
|
1266
1305
|
},
|
|
1267
1306
|
create(context) {
|
|
1268
1307
|
return {
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1308
|
+
ExportAllDeclaration: (node) => reportName(context, node, 'parsers.ts'),
|
|
1309
|
+
ExportNamedDeclaration: (node) => reportName(context, node, 'parsers.ts'),
|
|
1310
|
+
FunctionDeclaration: (node) => reportName(context, node, 'parsers.ts'),
|
|
1311
|
+
TSDeclareFunction: (node) => reportName(context, node, 'parsers.ts'),
|
|
1312
|
+
VariableDeclaration: (node) => reportName(context, node, 'parsers.ts'),
|
|
1272
1313
|
}
|
|
1273
1314
|
},
|
|
1274
1315
|
}
|
|
1275
1316
|
|
|
1276
|
-
/** Bans a factories.ts function whose name lacks the create prefix. */
|
|
1317
|
+
/** Bans a factories.ts function or export whose name lacks the create prefix. */
|
|
1277
1318
|
export const FACTORY_RULE: PolicyRuleInterface = {
|
|
1278
1319
|
meta: {
|
|
1279
1320
|
type: 'problem',
|
|
1280
1321
|
docs: {
|
|
1281
|
-
description:
|
|
1322
|
+
description:
|
|
1323
|
+
'Disallow a factories.ts function or export whose name does not start with create.',
|
|
1282
1324
|
},
|
|
1283
1325
|
messages: {
|
|
1284
1326
|
factory:
|
|
1285
|
-
'Name this factories.ts function with the create prefix, or move it to its own kind file.',
|
|
1327
|
+
'Name this factories.ts function or export with the create prefix, or move it to its own kind file.',
|
|
1328
|
+
},
|
|
1329
|
+
},
|
|
1330
|
+
create(context) {
|
|
1331
|
+
return {
|
|
1332
|
+
ExportAllDeclaration: (node) => reportName(context, node, 'factories.ts'),
|
|
1333
|
+
ExportNamedDeclaration: (node) => reportName(context, node, 'factories.ts'),
|
|
1334
|
+
FunctionDeclaration: (node) => reportName(context, node, 'factories.ts'),
|
|
1335
|
+
TSDeclareFunction: (node) => reportName(context, node, 'factories.ts'),
|
|
1336
|
+
VariableDeclaration: (node) => reportName(context, node, 'factories.ts'),
|
|
1337
|
+
}
|
|
1338
|
+
},
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
/** Bans a plugins.ts function or export whose name is not a create-prefixed plugin or plugins form. */
|
|
1342
|
+
export const PLUGIN_RULE: PolicyRuleInterface = {
|
|
1343
|
+
meta: {
|
|
1344
|
+
type: 'problem',
|
|
1345
|
+
docs: {
|
|
1346
|
+
description:
|
|
1347
|
+
'Disallow a plugins.ts function or export whose name is not create…Plugin or create…Plugins.',
|
|
1348
|
+
},
|
|
1349
|
+
messages: {
|
|
1350
|
+
plugin:
|
|
1351
|
+
'Name this plugins.ts function or export create…Plugin, or create…Plugins for a collection, or move it to its own kind file.',
|
|
1286
1352
|
},
|
|
1287
1353
|
},
|
|
1288
1354
|
create(context) {
|
|
1289
1355
|
return {
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1356
|
+
ExportAllDeclaration: (node) => reportName(context, node, 'plugins.ts'),
|
|
1357
|
+
ExportNamedDeclaration: (node) => reportName(context, node, 'plugins.ts'),
|
|
1358
|
+
FunctionDeclaration: (node) => reportName(context, node, 'plugins.ts'),
|
|
1359
|
+
TSDeclareFunction: (node) => reportName(context, node, 'plugins.ts'),
|
|
1360
|
+
VariableDeclaration: (node) => reportName(context, node, 'plugins.ts'),
|
|
1293
1361
|
}
|
|
1294
1362
|
},
|
|
1295
1363
|
}
|
|
@@ -1392,6 +1460,7 @@ export default {
|
|
|
1392
1460
|
'no-malformed-constant': CONSTANT_RULE,
|
|
1393
1461
|
'no-misnamed-parser': PARSER_RULE,
|
|
1394
1462
|
'no-misnamed-factory': FACTORY_RULE,
|
|
1463
|
+
'no-misnamed-plugin': PLUGIN_RULE,
|
|
1395
1464
|
'no-malformed-domain': DOMAIN_RULE,
|
|
1396
1465
|
'no-host-line-endings': ENDING_RULE,
|
|
1397
1466
|
'no-malformed-summary': VOICE_RULE,
|