@cap-js/cds-typer 0.8.0 → 0.9.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/CHANGELOG.md +11 -1
- package/lib/csn.js +267 -0
- package/lib/util.js +1 -62
- package/lib/visitor.js +16 -4
- package/package.json +2 -7
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
6
6
|
|
|
7
|
-
## Version 0.
|
|
7
|
+
## Version 0.9.1 - TBD
|
|
8
8
|
|
|
9
9
|
### Changed
|
|
10
10
|
|
|
@@ -12,6 +12,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
|
12
12
|
|
|
13
13
|
### Fixed
|
|
14
14
|
|
|
15
|
+
## Version 0.9.0 - 2023-09-08
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- Support for drafts via `@odata.draft.enabled` annotation
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- Foreign keys are now propagated more than one level (think: `x_ID_ID_ID`)
|
|
24
|
+
|
|
15
25
|
|
|
16
26
|
## Version 0.8.0 - 2023-09-05
|
|
17
27
|
|
package/lib/csn.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
const annotation = '@odata.draft.enabled'
|
|
2
|
+
|
|
3
|
+
class DraftUnroller {
|
|
4
|
+
/** @type {Set<string>} */
|
|
5
|
+
#positives = new Set()
|
|
6
|
+
/** @type {{[key: string]: boolean}} */
|
|
7
|
+
#draftable = {}
|
|
8
|
+
/** @type {{[key: string]: string}} */
|
|
9
|
+
#projections
|
|
10
|
+
/** @type {object[]} */
|
|
11
|
+
#entities
|
|
12
|
+
#csn
|
|
13
|
+
set csn(c) {
|
|
14
|
+
this.#csn = c
|
|
15
|
+
this.#entities = Object.values(c.definitions)
|
|
16
|
+
this.#projections = this.#entities.reduce((pjs, entity) => {
|
|
17
|
+
if (entity.projection) {
|
|
18
|
+
pjs[entity.name] = entity.projection.from.ref[0]
|
|
19
|
+
}
|
|
20
|
+
return pjs
|
|
21
|
+
}, {})
|
|
22
|
+
}
|
|
23
|
+
get csn() { return this.#csn }
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param entity {object | string} - entity to set draftable annotation for.
|
|
27
|
+
* @param value {boolean} - whether the entity is draftable.
|
|
28
|
+
*/
|
|
29
|
+
#setDraftable(entity, value) {
|
|
30
|
+
if (typeof entity === 'string') entity = this.#getDefinition(entity)
|
|
31
|
+
entity[annotation] = value
|
|
32
|
+
this.#draftable[entity.name] = value
|
|
33
|
+
if (value) {
|
|
34
|
+
this.#positives.add(entity.name)
|
|
35
|
+
} else {
|
|
36
|
+
this.#positives.delete(entity.name)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param entity {object | string} - entity to look draftability up for.
|
|
42
|
+
* @returns {boolean}
|
|
43
|
+
*/
|
|
44
|
+
#getDraftable(entity) {
|
|
45
|
+
if (typeof entity === 'string') entity = this.#getDefinition(entity)
|
|
46
|
+
return this.#draftable[entity.name] ??= this.#propagateInheritance(entity)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param name {string} - name of the entity.
|
|
51
|
+
*/
|
|
52
|
+
#getDefinition(name) { return this.csn.definitions[name] }
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Propagate draft annotations through inheritance (includes).
|
|
56
|
+
* The latest annotation through the inheritance chain "wins".
|
|
57
|
+
* Annotations on the entity itself are always queued last, so they will always be decisive over ancestors.
|
|
58
|
+
*
|
|
59
|
+
* @param entity {object} - entity to pull draftability from its parents.
|
|
60
|
+
*/
|
|
61
|
+
#propagateInheritance(entity) {
|
|
62
|
+
const annotations = (entity.includes ?? []).map(parent => this.#getDraftable(parent))
|
|
63
|
+
annotations.push(entity[annotation])
|
|
64
|
+
this.#setDraftable(entity, annotations.filter(a => a !== undefined).at(-1) ?? false)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Propagate draft-enablement through projections.
|
|
69
|
+
*/
|
|
70
|
+
#propagateProjections() {
|
|
71
|
+
const propagate = (from, to) => {
|
|
72
|
+
do {
|
|
73
|
+
this.#setDraftable(to, this.#getDraftable(to) || this.#getDraftable(from))
|
|
74
|
+
from = to
|
|
75
|
+
to = this.#projections[to]
|
|
76
|
+
} while (to)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (let [projection, target] of Object.entries(this.#projections)) {
|
|
80
|
+
propagate(projection, target)
|
|
81
|
+
propagate(target, projection)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* If an entity E is draftable and contains any composition of entities,
|
|
87
|
+
* then those entities also become draftable. Recursively.
|
|
88
|
+
*
|
|
89
|
+
* @param entity {object} - entity to propagate all compositions from.
|
|
90
|
+
*/
|
|
91
|
+
#propagateCompositions(entity) {
|
|
92
|
+
if (!this.#getDraftable(entity)) return
|
|
93
|
+
|
|
94
|
+
for (const comp of Object.values(entity.compositions ?? {})) {
|
|
95
|
+
const target = this.#getDefinition(comp.target)
|
|
96
|
+
const current = this.#getDraftable(target)
|
|
97
|
+
if (!current) {
|
|
98
|
+
this.#setDraftable(target, true)
|
|
99
|
+
this.#propagateCompositions(target)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
unroll(csn) {
|
|
105
|
+
this.csn = csn
|
|
106
|
+
|
|
107
|
+
// inheritance
|
|
108
|
+
for (const entity of this.#entities) {
|
|
109
|
+
this.#propagateInheritance(entity)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// transitivity through compositions
|
|
113
|
+
// we have to do this in a second pass, as we only now know which entities are draft-enables themselves
|
|
114
|
+
for (const entity of this.#entities) {
|
|
115
|
+
this.#propagateCompositions(entity)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.#propagateProjections()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// note to self: following doc uses @ homoglyph instead of @, as the latter apparently has special semantics in code listings
|
|
123
|
+
/**
|
|
124
|
+
* We are unrolling the @odata.draft.enabled annotations into related entities manually.
|
|
125
|
+
* This includes three scenarios:
|
|
126
|
+
*
|
|
127
|
+
* (a) aspects via `A: B`, where `B` is draft enabled.
|
|
128
|
+
* Note that when an entity extends two other entities of which one has drafts enabled and
|
|
129
|
+
* one has not, then the one that is later in the list of mixins "wins":
|
|
130
|
+
* @example sdasd
|
|
131
|
+
* ```ts
|
|
132
|
+
* @odata.draft.enabled true
|
|
133
|
+
* entity T {}
|
|
134
|
+
* @odata.draft.enabled false
|
|
135
|
+
* entity F {}
|
|
136
|
+
* entity A: T,F {} // draft not enabled
|
|
137
|
+
* entity B: F,T {} // draft enabled
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* (b) Draft enabled projections make the entity we project on draft enabled.
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* @odata.draft.enabled: true
|
|
144
|
+
* entity A as projection on B {}
|
|
145
|
+
* entity B {} // draft enabled
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* (c) Entities that are draft enabled propagate this property down through compositions:
|
|
149
|
+
*
|
|
150
|
+
* ```ts
|
|
151
|
+
* @odata.draft.enabled: true
|
|
152
|
+
* entity A {
|
|
153
|
+
* b: Composition of B
|
|
154
|
+
* }
|
|
155
|
+
* entity B {} // draft enabled
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
function unrollDraftability(csn) {
|
|
159
|
+
new DraftUnroller().unroll(csn)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Propagates keys elements through the CSN. This includes
|
|
164
|
+
*
|
|
165
|
+
* (a) keys that are explicitly declared as key in an entity
|
|
166
|
+
* (b) keys from aspects the entity extends
|
|
167
|
+
*
|
|
168
|
+
* This explicit propagation is required to add foreign key relations
|
|
169
|
+
* to referring entities.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```cds
|
|
173
|
+
* entity A: cuid { key name: String; }
|
|
174
|
+
* entity B { ref: Association to one A }
|
|
175
|
+
* ```
|
|
176
|
+
* must yield
|
|
177
|
+
* ```ts
|
|
178
|
+
* class A {
|
|
179
|
+
* ID: UUID // inherited from cuid
|
|
180
|
+
* name: String;
|
|
181
|
+
* }
|
|
182
|
+
* class B {
|
|
183
|
+
* ref: Association.to<A>
|
|
184
|
+
* ref_ID: UUID
|
|
185
|
+
* ref_name: String;
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
* @returns {{[key: string]: object}}
|
|
189
|
+
*/
|
|
190
|
+
function propagateForeignKeys(csn) {
|
|
191
|
+
for (const element of Object.values(csn.definitions)) {
|
|
192
|
+
Object.defineProperty(element, 'keys', {
|
|
193
|
+
get: function () {
|
|
194
|
+
// cached access to all immediately defined _and_ inherited keys.
|
|
195
|
+
// They need to be explicitly accessible in subclasses to generate
|
|
196
|
+
// foreign key fields from Associations/ Compositions.
|
|
197
|
+
if (!Object.hasOwn(this, '__keys')) {
|
|
198
|
+
const ownKeys = Object.entries(this.elements ?? {}).filter(([,el]) => el.key === true)
|
|
199
|
+
const inheritedKeys = this.includes?.flatMap(parent => Object.entries(csn.definitions[parent].keys)) ?? []
|
|
200
|
+
// not sure why, but .associations contains both Associations, as well as Compositions in CSN.
|
|
201
|
+
// (.compositions contains only Compositions, if any)
|
|
202
|
+
const remoteKeys = Object.entries(this.associations ?? {})
|
|
203
|
+
.filter(([,{key}]) => key) // only follow associations that are keys, that way we avoid cycles
|
|
204
|
+
.flatMap(([kname, key]) => Object.entries(csn.definitions[key.target].keys)
|
|
205
|
+
.map(([ckname, ckey]) => [`${kname}_${ckname}`, ckey]))
|
|
206
|
+
|
|
207
|
+
this.__keys = Object.fromEntries(ownKeys
|
|
208
|
+
.concat(inheritedKeys)
|
|
209
|
+
.concat(remoteKeys)
|
|
210
|
+
.filter(([,ckey]) => !ckey.target) // discard keys that are Associations. Those are already part of .elements
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
return this.__keys
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Entities inherit their ancestors annotations:
|
|
221
|
+
* https://cap.cloud.sap/docs/cds/cdl#annotation-propagation
|
|
222
|
+
* This is a problem if we annotate @singular/ @plural to an entity A,
|
|
223
|
+
* as we don't want all descendents B, C, ... to share the ancestor's
|
|
224
|
+
* annotated inflexion
|
|
225
|
+
* -> remove all such annotations that appear in a parent as well.
|
|
226
|
+
* BUT: we can't just delete the attributes. Imagine three classes
|
|
227
|
+
* A <- B <- C
|
|
228
|
+
* where A contains a @singular annotation.
|
|
229
|
+
* If we erase the annotation from B, C will still contain it and
|
|
230
|
+
* can not detect that its own annotation was inherited without
|
|
231
|
+
* travelling up the entire inheritance chain up to A.
|
|
232
|
+
* So instead, we monkey patch and maintain a dictionary "erased"
|
|
233
|
+
* when removing an annotation which we also check.
|
|
234
|
+
* @deprecated since we use the xtended flavour for CSN, we don't need to fix this anymore
|
|
235
|
+
*/
|
|
236
|
+
function propagateInflectionAnnotations(csn) {
|
|
237
|
+
const erase = (entity, parent, attr) => {
|
|
238
|
+
if (attr in entity) {
|
|
239
|
+
const ea = entity[attr]
|
|
240
|
+
if (parent[attr] === ea || (parent.erased && parent.erased[attr] === ea)) {
|
|
241
|
+
entity.erased ??= {}
|
|
242
|
+
entity.erased[attr] = ea
|
|
243
|
+
delete entity[attr]
|
|
244
|
+
//this.logger.info(`Removing inherited attribute ${attr} from ${entity.name}.`)
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
for (const entity of Object.values(csn.definitions)) {
|
|
250
|
+
let i = 0
|
|
251
|
+
while (
|
|
252
|
+
(getSingularAnnotation(entity) || getPluralAnnotation(entity)) &&
|
|
253
|
+
i < (entity.includes ?? []).length
|
|
254
|
+
) {
|
|
255
|
+
const parent = csn.definitions[entity.includes[i]]
|
|
256
|
+
Object.values(annotations).flat().forEach(an => erase(entity, parent, an))
|
|
257
|
+
i++
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function amendCSN(csn) {
|
|
263
|
+
unrollDraftability(csn)
|
|
264
|
+
propagateForeignKeys(csn)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
module.exports = { amendCSN }
|
package/lib/util.js
CHANGED
|
@@ -184,66 +184,6 @@ const parseCommandlineArgs = (argv, validFlags) => {
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
/**
|
|
188
|
-
* Entities inherit their ancestors annotations:
|
|
189
|
-
* https://cap.cloud.sap/docs/cds/cdl#annotation-propagation
|
|
190
|
-
* This is a problem if we annotate @singular/ @plural to an entity A,
|
|
191
|
-
* as we don't want all descendents B, C, ... to share the ancestor's
|
|
192
|
-
* annotated inflexion
|
|
193
|
-
* -> remove all such annotations that appear in a parent as well.
|
|
194
|
-
* BUT: we can't just delete the attributes. Imagine three classes
|
|
195
|
-
* A <- B <- C
|
|
196
|
-
* where A contains a @singular annotation.
|
|
197
|
-
* If we erase the annotation from B, C will still contain it and
|
|
198
|
-
* can not detect that its own annotation was inherited without
|
|
199
|
-
* travelling up the entire inheritance chain up to A.
|
|
200
|
-
* So instead, we monkey patch and maintain a dictionary "erased"
|
|
201
|
-
* when removing an annotation which we also check.
|
|
202
|
-
*/
|
|
203
|
-
function fixCSN(csn) {
|
|
204
|
-
for (const element of Object.values(csn.definitions)) {
|
|
205
|
-
Object.defineProperty(element, 'keys', {
|
|
206
|
-
get: function () {
|
|
207
|
-
// cached access to all immediately defined _and_ inherited keys.
|
|
208
|
-
// They need to be explicitly accessible in subclasses to generate
|
|
209
|
-
// foreign key fields from Associations/ Compositions.
|
|
210
|
-
if (!Object.hasOwn(this, '__keys')) {
|
|
211
|
-
const ownKeys = Object.fromEntries(Object.entries(this.elements ?? {}).filter(([,el]) => el.key === true))
|
|
212
|
-
const inheritedKeys = this.includes?.flatMap(parent => csn.definitions[parent].keys) ?? []
|
|
213
|
-
this.__keys = inheritedKeys.reduce((ks, ps) => ({...ps, ...ks}), ownKeys)
|
|
214
|
-
}
|
|
215
|
-
return this.__keys
|
|
216
|
-
}
|
|
217
|
-
})
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// FIXME: delete after merge with draft-enablement PR
|
|
221
|
-
return
|
|
222
|
-
const erase = (entity, parent, attr) => {
|
|
223
|
-
if (attr in entity) {
|
|
224
|
-
const ea = entity[attr]
|
|
225
|
-
if (parent[attr] === ea || (parent.erased && parent.erased[attr] === ea)) {
|
|
226
|
-
entity.erased ??= {}
|
|
227
|
-
entity.erased[attr] = ea
|
|
228
|
-
delete entity[attr]
|
|
229
|
-
//this.logger.info(`Removing inherited attribute ${attr} from ${entity.name}.`)
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
for (const entity of Object.values(csn.definitions)) {
|
|
235
|
-
let i = 0
|
|
236
|
-
while (
|
|
237
|
-
(getSingularAnnotation(entity) || getPluralAnnotation(entity)) &&
|
|
238
|
-
i < (entity.includes ?? []).length
|
|
239
|
-
) {
|
|
240
|
-
const parent = csn.definitions[entity.includes[i]]
|
|
241
|
-
Object.values(annotations).flat().forEach(an => erase(entity, parent, an))
|
|
242
|
-
i++
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
187
|
module.exports = {
|
|
248
188
|
annotations,
|
|
249
189
|
getSingularAnnotation,
|
|
@@ -252,6 +192,5 @@ module.exports = {
|
|
|
252
192
|
singular4,
|
|
253
193
|
plural4,
|
|
254
194
|
parseCommandlineArgs,
|
|
255
|
-
deepMerge
|
|
256
|
-
fixCSN
|
|
195
|
+
deepMerge
|
|
257
196
|
}
|
package/lib/visitor.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const util = require('./util')
|
|
4
4
|
|
|
5
|
+
const { amendCSN } = require('./csn')
|
|
5
6
|
const { SourceFile, baseDefinitions, Buffer } = require('./file')
|
|
6
7
|
const { FlatInlineDeclarationResolver, StructuredInlineDeclarationResolver } = require('./components/inline')
|
|
7
8
|
const { Resolver } = require('./components/resolver')
|
|
@@ -59,7 +60,7 @@ class Visitor {
|
|
|
59
60
|
* @param {VisitorOptions} options
|
|
60
61
|
*/
|
|
61
62
|
constructor(csn, options = {}, logger = new Logger()) {
|
|
62
|
-
|
|
63
|
+
amendCSN(csn)
|
|
63
64
|
this.options = { ...defaults, ...options }
|
|
64
65
|
this.logger = logger
|
|
65
66
|
this.csn = csn
|
|
@@ -128,8 +129,10 @@ class Visitor {
|
|
|
128
129
|
buffer.indent()
|
|
129
130
|
buffer.add(`return class ${clean} extends Base {`)
|
|
130
131
|
buffer.indent()
|
|
132
|
+
|
|
131
133
|
for (const [ename, element] of Object.entries(entity.elements ?? {})) {
|
|
132
134
|
this.visitElement(ename, element, file, buffer)
|
|
135
|
+
|
|
133
136
|
// make foreign keys explicit
|
|
134
137
|
if ('target' in element) {
|
|
135
138
|
// lookup in cds.definitions can fail for inline structs.
|
|
@@ -139,7 +142,8 @@ class Visitor {
|
|
|
139
142
|
this.visitElement(`${ename}_${kname}`, kelement, file, buffer)
|
|
140
143
|
}
|
|
141
144
|
}
|
|
142
|
-
}
|
|
145
|
+
}
|
|
146
|
+
|
|
143
147
|
for (const [aname, action] of Object.entries(entity.actions ?? {})) {
|
|
144
148
|
buffer.add(
|
|
145
149
|
SourceFile.stringifyLambda({
|
|
@@ -173,11 +177,19 @@ class Visitor {
|
|
|
173
177
|
`${baseDefinitions.path.asIdentifier()}.Entity`
|
|
174
178
|
)
|
|
175
179
|
|
|
176
|
-
buffer.add(`export class ${identSingular(clean)} extends ${rhs} {}`)
|
|
180
|
+
buffer.add(`export class ${identSingular(clean)} extends ${rhs} {${this.#staticClassContents(clean, entity).join('\n')}}`)
|
|
177
181
|
//buffer.add(`export type ${clean} = InstanceType<typeof ${identSingular(clean)}>`)
|
|
178
182
|
this.contexts.pop()
|
|
179
183
|
}
|
|
180
184
|
|
|
185
|
+
#isDraftEnabled(entity) {
|
|
186
|
+
return entity['@odata.draft.enabled'] === true
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
#staticClassContents(clean, entity) {
|
|
190
|
+
return this.#isDraftEnabled(entity) ? [`static drafts: typeof ${clean}`] : []
|
|
191
|
+
}
|
|
192
|
+
|
|
181
193
|
#printEntity(name, entity) {
|
|
182
194
|
const clean = this.resolver.trimNamespace(name)
|
|
183
195
|
const ns = this.resolver.resolveNamespace(name.split('.'))
|
|
@@ -228,7 +240,7 @@ class Visitor {
|
|
|
228
240
|
}
|
|
229
241
|
// plural can not be a type alias to $singular[] but needs to be a proper class instead,
|
|
230
242
|
// so it can get passed as value to CQL functions.
|
|
231
|
-
buffer.add(`export class ${plural} extends Array<${singular}> {}`)
|
|
243
|
+
buffer.add(`export class ${plural} extends Array<${singular}> {${this.#staticClassContents(singular, entity).join('\n')}}`)
|
|
232
244
|
buffer.add('')
|
|
233
245
|
}
|
|
234
246
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js/cds-typer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Generates .ts files for a CDS model to receive code completion in VS Code",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": "github:cap-js/cds-typer",
|
|
@@ -22,10 +22,7 @@
|
|
|
22
22
|
"doc:clean": "rm -rf ./doc",
|
|
23
23
|
"doc:prepare": "npm run doc:clean && mkdir -p doc/types",
|
|
24
24
|
"doc:typegen": "./node_modules/.bin/tsc ./lib/*.js --skipLibCheck --declaration --allowJs --emitDeclarationOnly --outDir doc/types && cd doc/types && tsc --init",
|
|
25
|
-
"doc:
|
|
26
|
-
"doc:md": "npm run doc:typegen && ./node_modules/.bin/typedoc --plugin typedoc-plugin-markdown 'doc/types/compile.d.ts' --out doc/md --tsconfig doc/types/tsconfig.json",
|
|
27
|
-
"doc:cli": "npm run cli -- --help > ./doc/cli.txt",
|
|
28
|
-
"doc:full": "npm run doc:prepare && npm run doc:html && npm run doc:cli"
|
|
25
|
+
"doc:cli": "npm run cli -- --help > ./doc/cli.txt"
|
|
29
26
|
},
|
|
30
27
|
"files": [
|
|
31
28
|
"lib/",
|
|
@@ -48,8 +45,6 @@
|
|
|
48
45
|
"eslint-config-prettier": "^8.5.0",
|
|
49
46
|
"eslint-plugin-prettier": "^4.0.0",
|
|
50
47
|
"jest": "^29",
|
|
51
|
-
"typedoc": "^0.24.8",
|
|
52
|
-
"typedoc-plugin-markdown": "^3.15.3",
|
|
53
48
|
"typescript": ">=4.6.4"
|
|
54
49
|
},
|
|
55
50
|
"jest": {
|