adapt-project 1.0.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/.github/workflows/releases.yml +32 -0
- package/.github/workflows/standardjs.yml +13 -0
- package/.github/workflows/tests.yml +13 -0
- package/README.md +168 -0
- package/eslint.config.js +10 -0
- package/index.js +13 -0
- package/lib/Data.js +185 -0
- package/lib/Framework.js +295 -0
- package/lib/JSONFile.js +104 -0
- package/lib/JSONFileItem.js +27 -0
- package/lib/Plugins.js +82 -0
- package/lib/Schemas.js +208 -0
- package/lib/Translate.js +495 -0
- package/lib/data/Language.js +301 -0
- package/lib/data/LanguageFile.js +35 -0
- package/lib/plugins/Plugin.js +143 -0
- package/lib/schema/ExtensionSchema.js +26 -0
- package/lib/schema/GlobalsSchema.js +65 -0
- package/lib/schema/ModelSchema.js +45 -0
- package/lib/schema/ModelSchemas.js +41 -0
- package/lib/schema/Schema.js +191 -0
- package/package.json +54 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
import fs from 'fs-extra'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('../Framework')} Framework
|
|
6
|
+
* @typedef {import('../JSONFileItem')} JSONFileItem
|
|
7
|
+
* @typedef {import('../plugins/Plugin')} Plugin
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
class Schema {
|
|
11
|
+
/**
|
|
12
|
+
* @param {Object} options
|
|
13
|
+
* @param {Framework} options.framework
|
|
14
|
+
* @param {string} options.name
|
|
15
|
+
* @param {Plugin} options.plugin
|
|
16
|
+
* @param {Object} options.json
|
|
17
|
+
* @param {string} options.filePath
|
|
18
|
+
* @param {string} options.globalsType
|
|
19
|
+
*/
|
|
20
|
+
constructor ({
|
|
21
|
+
framework = null,
|
|
22
|
+
name = '',
|
|
23
|
+
plugin = null,
|
|
24
|
+
json = null,
|
|
25
|
+
filePath = '',
|
|
26
|
+
globalsType = ''
|
|
27
|
+
} = {}) {
|
|
28
|
+
/** @type {Framework} */
|
|
29
|
+
this.framework = framework
|
|
30
|
+
/** @type {Plugin} */
|
|
31
|
+
this.plugin = plugin
|
|
32
|
+
/** @type {string} */
|
|
33
|
+
this.name = name
|
|
34
|
+
/** @type {Object} */
|
|
35
|
+
this.json = json
|
|
36
|
+
/** @type {string} */
|
|
37
|
+
this.filePath = filePath
|
|
38
|
+
/** @type {string} */
|
|
39
|
+
this.globalsType = globalsType
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** @returns {Schema} */
|
|
43
|
+
load () {
|
|
44
|
+
this.json = fs.readJSONSync(this.filePath)
|
|
45
|
+
return this
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Walk through schema properties and an object's attributes calling an
|
|
50
|
+
* iterator function with the attributeName, attributeType and schema
|
|
51
|
+
* description along with the framework object, the current object attribute
|
|
52
|
+
* node and any other pass-through arguments.
|
|
53
|
+
* @param {string} schemaPath The attribute path from which to start in the schema
|
|
54
|
+
* @param {SchemaTraverseIterator} iterator
|
|
55
|
+
* @param {...any} args pass-through arguments
|
|
56
|
+
* @returns {Schema}
|
|
57
|
+
*/
|
|
58
|
+
traverse (schemaPath, iterator, ...args) {
|
|
59
|
+
let shouldStop = false
|
|
60
|
+
const json = schemaPath ? _.get(this.json.properties, schemaPath) : this.json
|
|
61
|
+
const recursiveSchemaNodeProperties = (properties, ...args) => {
|
|
62
|
+
let rtnValue = false
|
|
63
|
+
// process properties
|
|
64
|
+
for (const attributeName in properties) {
|
|
65
|
+
let description = properties[attributeName]
|
|
66
|
+
if (Object.prototype.hasOwnProperty.call(description, 'editorOnly') || !Object.prototype.hasOwnProperty.call(description, 'type')) {
|
|
67
|
+
// go to next attribute
|
|
68
|
+
continue
|
|
69
|
+
}
|
|
70
|
+
description = { framework: this.framework, name: attributeName, ...description }
|
|
71
|
+
// process current properties attribute
|
|
72
|
+
const returned = iterator({
|
|
73
|
+
description,
|
|
74
|
+
next: (...args) => {
|
|
75
|
+
// continue with recursion if able
|
|
76
|
+
switch (description.type) {
|
|
77
|
+
case 'object':
|
|
78
|
+
return recursiveSchemaNodeProperties(description.properties, ...args)
|
|
79
|
+
case 'array': {
|
|
80
|
+
if (description.items.type === 'object') {
|
|
81
|
+
return recursiveSchemaNodeProperties(description.items.properties, ...args)
|
|
82
|
+
}
|
|
83
|
+
const next = {}
|
|
84
|
+
next[attributeName] = description.items
|
|
85
|
+
return recursiveSchemaNodeProperties(next, ...args)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
stop: () => {
|
|
90
|
+
shouldStop = true
|
|
91
|
+
}
|
|
92
|
+
}, ...args)
|
|
93
|
+
rtnValue = rtnValue || returned
|
|
94
|
+
if (shouldStop) {
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
recursiveSchemaNodeProperties(json.properties, ...args)
|
|
100
|
+
return this
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Applies schema defaults to the given object.
|
|
105
|
+
* @param {Object} output
|
|
106
|
+
* @param {string} schemaPath
|
|
107
|
+
* @param {Object} options
|
|
108
|
+
* @param {boolean} options.fillObjects Infer array or object default objects
|
|
109
|
+
* @returns {Schema}
|
|
110
|
+
*/
|
|
111
|
+
applyDefaults (output = {}, schemaPath, options = { fillObjects: true }) {
|
|
112
|
+
function sortKeys (object) {
|
|
113
|
+
const keys = Object.keys(object).sort((a, b) => {
|
|
114
|
+
return a.localeCompare(b)
|
|
115
|
+
})
|
|
116
|
+
keys.forEach(name => {
|
|
117
|
+
const value = object[name]
|
|
118
|
+
delete object[name]
|
|
119
|
+
object[name] = value
|
|
120
|
+
})
|
|
121
|
+
return object
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
this.traverse(schemaPath, ({ description, next }, output) => {
|
|
125
|
+
let hasChanged = false
|
|
126
|
+
let haveChildenChanged = false
|
|
127
|
+
let defaultValue
|
|
128
|
+
|
|
129
|
+
if (description === null || output === null) return
|
|
130
|
+
|
|
131
|
+
switch (description.type) {
|
|
132
|
+
case 'object':
|
|
133
|
+
defaultValue = Object.prototype.hasOwnProperty.call(description, 'default') && options.fillObjects ? description.default : {}
|
|
134
|
+
if (!Object.prototype.hasOwnProperty.call(output, description.name)) {
|
|
135
|
+
output[description.name] = defaultValue
|
|
136
|
+
hasChanged = true
|
|
137
|
+
}
|
|
138
|
+
haveChildenChanged = next(output[description.name])
|
|
139
|
+
if (haveChildenChanged) {
|
|
140
|
+
sortKeys(output[description.name])
|
|
141
|
+
}
|
|
142
|
+
break
|
|
143
|
+
case 'array':
|
|
144
|
+
defaultValue = Object.prototype.hasOwnProperty.call(description, 'default') && options.fillObjects ? description.default : []
|
|
145
|
+
if (!Object.prototype.hasOwnProperty.call(output, description.name)) {
|
|
146
|
+
output[description.name] = defaultValue
|
|
147
|
+
hasChanged = true
|
|
148
|
+
}
|
|
149
|
+
haveChildenChanged = next(output[description.name])
|
|
150
|
+
if (haveChildenChanged) {
|
|
151
|
+
sortKeys(output[description.name])
|
|
152
|
+
}
|
|
153
|
+
break
|
|
154
|
+
default:
|
|
155
|
+
defaultValue = description.default
|
|
156
|
+
if (Object.prototype.hasOwnProperty.call(description, 'default') && !Object.prototype.hasOwnProperty.call(output, description.name)) {
|
|
157
|
+
output[description.name] = defaultValue
|
|
158
|
+
hasChanged = true
|
|
159
|
+
}
|
|
160
|
+
break
|
|
161
|
+
}
|
|
162
|
+
return hasChanged
|
|
163
|
+
}, output)
|
|
164
|
+
|
|
165
|
+
return output
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* @typedef SchemaNodeDescription
|
|
171
|
+
* @property {Framework} framework Schema properties node
|
|
172
|
+
* @property {string} name Attribute name
|
|
173
|
+
* @property {string} type Attribute type
|
|
174
|
+
* @property {boolean} editorOnly
|
|
175
|
+
*/
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @typedef SchemaTraverseIteratorParam0
|
|
179
|
+
* @property {SchemaNodeDescription} description
|
|
180
|
+
* @property {function} next
|
|
181
|
+
* @property {function} stop
|
|
182
|
+
*/
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Iterator function for schema.traverse.
|
|
186
|
+
* @callback SchemaTraverseIterator
|
|
187
|
+
* @param {SchemaTraverseIteratorParam0} config
|
|
188
|
+
* @param {...any} args pass-through arguments
|
|
189
|
+
*/
|
|
190
|
+
|
|
191
|
+
export default Schema
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "adapt-project",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Adapt Framework project helpers - plugins, schemas, data and translations",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "GPL-3.0",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"lint": "eslint .",
|
|
10
|
+
"lint:fix": "eslint . --fix"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"async": "^3.2.2",
|
|
14
|
+
"chalk": "^2.4.1",
|
|
15
|
+
"csv": "^5.5.3",
|
|
16
|
+
"fast-xml-parser": "^4.5.0",
|
|
17
|
+
"fs-extra": "^8.1.0",
|
|
18
|
+
"globs": "^0.1.4",
|
|
19
|
+
"iconv-lite": "^0.6.3",
|
|
20
|
+
"jschardet": "^1.6.0",
|
|
21
|
+
"lodash": "^4.17.23",
|
|
22
|
+
"semver": "^7.6.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@semantic-release/git": "^10.0.1",
|
|
26
|
+
"conventional-changelog-eslint": "^6.0.0",
|
|
27
|
+
"semantic-release": "^25.0.3",
|
|
28
|
+
"@eslint/eslintrc": "^3.1.0",
|
|
29
|
+
"eslint": "^8.57.0",
|
|
30
|
+
"eslint-config-standard": "^17.1.0",
|
|
31
|
+
"eslint-plugin-import": "^2.29.0",
|
|
32
|
+
"eslint-plugin-n": "^16.6.0",
|
|
33
|
+
"eslint-plugin-promise": "^6.6.0"
|
|
34
|
+
},
|
|
35
|
+
"release": {
|
|
36
|
+
"plugins": [
|
|
37
|
+
[
|
|
38
|
+
"@semantic-release/commit-analyzer",
|
|
39
|
+
{
|
|
40
|
+
"preset": "eslint"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
"@semantic-release/release-notes-generator",
|
|
45
|
+
{
|
|
46
|
+
"preset": "eslint"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"@semantic-release/npm",
|
|
50
|
+
"@semantic-release/github",
|
|
51
|
+
"@semantic-release/git"
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|