@neurodevs/meta-node 0.19.15 → 0.19.17
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/.vscode/launch.json +53 -58
- package/.vscode/settings.json +62 -66
- package/.vscode/tasks.json +123 -129
- package/README.md +1 -0
- package/build/.spruce/settings.json +3 -7
- package/build/__tests__/AbstractAutomoduleTest.js +2 -4
- package/build/__tests__/AbstractAutomoduleTest.js.map +1 -1
- package/build/__tests__/AbstractPackageTest.d.ts +2 -0
- package/build/__tests__/AbstractPackageTest.js +4 -1
- package/build/__tests__/AbstractPackageTest.js.map +1 -1
- package/build/__tests__/impl/GitAutocloner.test.js +0 -3
- package/build/__tests__/impl/GitAutocloner.test.js.map +1 -1
- package/build/__tests__/impl/GitAutocommit.test.d.ts +2 -2
- package/build/__tests__/impl/GitAutocommit.test.js +3 -5
- package/build/__tests__/impl/GitAutocommit.test.js.map +1 -1
- package/build/__tests__/impl/NpmAutopackage.test.d.ts +18 -4
- package/build/__tests__/impl/NpmAutopackage.test.js +228 -26
- package/build/__tests__/impl/NpmAutopackage.test.js.map +1 -1
- package/build/__tests__/impl/NpmReleasePropagator.test.js +1 -4
- package/build/__tests__/impl/NpmReleasePropagator.test.js.map +1 -1
- package/build/__tests__/impl/NpmWorkspaceTypeChecker.test.js +0 -3
- package/build/__tests__/impl/NpmWorkspaceTypeChecker.test.js.map +1 -1
- package/build/impl/NpmAutopackage.d.ts +19 -1
- package/build/impl/NpmAutopackage.js +193 -14
- package/build/impl/NpmAutopackage.js.map +1 -1
- package/eslint.config.js +3 -0
- package/package.json +7 -5
- package/prettier.config.js +3 -0
- package/src/.spruce/settings.json +3 -7
- package/src/__tests__/AbstractAutomoduleTest.ts +2 -5
- package/src/__tests__/AbstractPackageTest.ts +6 -2
- package/src/__tests__/impl/GitAutocloner.test.ts +2 -5
- package/src/__tests__/impl/GitAutocommit.test.ts +4 -8
- package/src/__tests__/impl/NpmAutopackage.test.ts +291 -24
- package/src/__tests__/impl/NpmReleasePropagator.test.ts +3 -6
- package/src/__tests__/impl/NpmWorkspaceTypeChecker.test.ts +1 -5
- package/src/impl/NpmAutopackage.ts +248 -23
- package/tsconfig.json +24 -27
- package/eslint.config.mjs +0 -3
|
@@ -29,6 +29,10 @@ export default class NpmAutopackage implements Autopackage {
|
|
|
29
29
|
private originalTsconfig!: TsConfig
|
|
30
30
|
private metaNodeVersion!: string
|
|
31
31
|
|
|
32
|
+
private originalEslintConfig!: string
|
|
33
|
+
private originalPrettierConfig!: string
|
|
34
|
+
private originalSettingsJson!: string
|
|
35
|
+
|
|
32
36
|
private originalTasksJson!: {
|
|
33
37
|
tasks: unknown[]
|
|
34
38
|
inputs: unknown[]
|
|
@@ -46,6 +50,9 @@ export default class NpmAutopackage implements Autopackage {
|
|
|
46
50
|
private readonly tasksJsonPath: string
|
|
47
51
|
private readonly testDirPath: string
|
|
48
52
|
private readonly abstractTestPath: string
|
|
53
|
+
private readonly eslintConfigPath: string
|
|
54
|
+
private readonly prettierConfigPath: string
|
|
55
|
+
private readonly settingsJsonPath: string
|
|
49
56
|
|
|
50
57
|
private readonly abstractPackageTestFile = `import AbstractModuleTest from '@neurodevs/node-tdd'
|
|
51
58
|
|
|
@@ -64,6 +71,71 @@ export default esConfigNdx
|
|
|
64
71
|
private readonly prettierConfigFile = `import prettierConfigNdx from '@neurodevs/prettier-config-ndx'
|
|
65
72
|
|
|
66
73
|
export default prettierConfigNdx
|
|
74
|
+
`
|
|
75
|
+
|
|
76
|
+
private readonly settingsJsonFile = `{
|
|
77
|
+
"debug.node.autoAttach": "on",
|
|
78
|
+
"git.ignoreLimitWarning": true,
|
|
79
|
+
"javascript.validate.enable": false,
|
|
80
|
+
"files.watcherExclude": {
|
|
81
|
+
"**/.git/objects/**": true,
|
|
82
|
+
"**/.git/subtree-cache/**": true,
|
|
83
|
+
"**/build/**": true,
|
|
84
|
+
"**/node_modules/**": true
|
|
85
|
+
},
|
|
86
|
+
"search.exclude": {
|
|
87
|
+
"**/build/**": true,
|
|
88
|
+
"**/node_modules/**": true,
|
|
89
|
+
"**/.next/**": true
|
|
90
|
+
},
|
|
91
|
+
"editor.codeActionsOnSave": {
|
|
92
|
+
"source.fixAll.eslint": "always"
|
|
93
|
+
},
|
|
94
|
+
"editor.formatOnSave": true,
|
|
95
|
+
"editor.formatOnSaveMode": "file",
|
|
96
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
97
|
+
"editor.maxTokenizationLineLength": 20000000,
|
|
98
|
+
"[javascript]": {
|
|
99
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
100
|
+
"editor.formatOnSave": true
|
|
101
|
+
},
|
|
102
|
+
"[javascriptreact]": {
|
|
103
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
104
|
+
"editor.formatOnSave": true
|
|
105
|
+
},
|
|
106
|
+
"[typescript]": {
|
|
107
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
108
|
+
"editor.formatOnSave": true
|
|
109
|
+
},
|
|
110
|
+
"[typescriptreact]": {
|
|
111
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
112
|
+
"editor.formatOnSave": true
|
|
113
|
+
},
|
|
114
|
+
"eslint.enable": true,
|
|
115
|
+
"eslint.useFlatConfig": true,
|
|
116
|
+
"eslint.validate": [
|
|
117
|
+
"javascript",
|
|
118
|
+
"javascriptreact",
|
|
119
|
+
"typescript",
|
|
120
|
+
"typescriptreact"
|
|
121
|
+
],
|
|
122
|
+
"eslint.workingDirectories": ["./"],
|
|
123
|
+
"debug.javascript.unmapMissingSources": true,
|
|
124
|
+
"javascript.preferences.importModuleSpecifier": "relative",
|
|
125
|
+
"typescript.preferences.importModuleSpecifier": "relative",
|
|
126
|
+
"typescript.tsdk": "node_modules/typescript/lib",
|
|
127
|
+
"typescript.validate.enable": true,
|
|
128
|
+
"cSpell.ignorePaths": [
|
|
129
|
+
"**/package-lock.json",
|
|
130
|
+
"**/node_modules/**",
|
|
131
|
+
"**/build/**",
|
|
132
|
+
"**/vscode-extension/**",
|
|
133
|
+
"**/.git/objects/**",
|
|
134
|
+
".vscode",
|
|
135
|
+
".spruce"
|
|
136
|
+
],
|
|
137
|
+
"cSpell.words": ["arkit", "autogenerated", "scrollable", "serializable"]
|
|
138
|
+
}
|
|
67
139
|
`
|
|
68
140
|
|
|
69
141
|
protected constructor(options: AutopackageOptions) {
|
|
@@ -98,6 +170,19 @@ export default prettierConfigNdx
|
|
|
98
170
|
this.testDirPath,
|
|
99
171
|
'AbstractPackageTest.ts'
|
|
100
172
|
)
|
|
173
|
+
|
|
174
|
+
this.eslintConfigPath = path.join(this.packageDir, 'eslint.config.js')
|
|
175
|
+
|
|
176
|
+
this.prettierConfigPath = path.join(
|
|
177
|
+
this.packageDir,
|
|
178
|
+
'prettier.config.js'
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
this.settingsJsonPath = path.join(
|
|
182
|
+
this.packageDir,
|
|
183
|
+
'.vscode',
|
|
184
|
+
'settings.json'
|
|
185
|
+
)
|
|
101
186
|
}
|
|
102
187
|
|
|
103
188
|
public static Create(options: AutopackageOptions) {
|
|
@@ -119,9 +204,9 @@ export default prettierConfigNdx
|
|
|
119
204
|
await this.updateVscodeTasks()
|
|
120
205
|
await this.installDefaultDevDependencies()
|
|
121
206
|
await this.installAbstractPackageTest()
|
|
122
|
-
await this.
|
|
123
|
-
await this.installNewEslintConfigJs()
|
|
207
|
+
await this.installEslintConfigFile()
|
|
124
208
|
await this.installPrettierConfigFile()
|
|
209
|
+
await this.installSettingsJsonFile()
|
|
125
210
|
await this.openVscode()
|
|
126
211
|
}
|
|
127
212
|
|
|
@@ -280,6 +365,8 @@ export default prettierConfigNdx
|
|
|
280
365
|
}
|
|
281
366
|
|
|
282
367
|
private async updatePackageJsonFile() {
|
|
368
|
+
this.removeOldKeysFromPackageJson()
|
|
369
|
+
|
|
283
370
|
const ordered = this.orderJsonKeys(this.updatedPackageJson, [
|
|
284
371
|
'name',
|
|
285
372
|
'version',
|
|
@@ -297,7 +384,6 @@ export default prettierConfigNdx
|
|
|
297
384
|
'dependencies',
|
|
298
385
|
'devDependencies',
|
|
299
386
|
'jest',
|
|
300
|
-
'skill',
|
|
301
387
|
])
|
|
302
388
|
|
|
303
389
|
await this.writeFile(
|
|
@@ -307,6 +393,42 @@ export default prettierConfigNdx
|
|
|
307
393
|
)
|
|
308
394
|
}
|
|
309
395
|
|
|
396
|
+
private removeOldKeysFromPackageJson() {
|
|
397
|
+
const keysToRemove = [
|
|
398
|
+
'skill',
|
|
399
|
+
'jest.testPathIgnorePatterns',
|
|
400
|
+
'jest.moduleNameMapper',
|
|
401
|
+
'scripts.build.resolve-paths',
|
|
402
|
+
'scripts.lint.tsc',
|
|
403
|
+
'scripts.post.watch.build',
|
|
404
|
+
'scripts.resolve-paths.lint',
|
|
405
|
+
'scripts.watch.rebuild',
|
|
406
|
+
'scripts.watch.tsc',
|
|
407
|
+
]
|
|
408
|
+
|
|
409
|
+
for (const key of keysToRemove) {
|
|
410
|
+
this.deleteByPath(this.originalPackageJson, key)
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
private deleteByPath(obj: any, path: string): void {
|
|
415
|
+
const dot = path.indexOf('.')
|
|
416
|
+
|
|
417
|
+
if (dot === -1) {
|
|
418
|
+
delete obj[path]
|
|
419
|
+
return
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const parentKey = path.slice(0, dot)
|
|
423
|
+
const childKey = path.slice(dot + 1)
|
|
424
|
+
|
|
425
|
+
const parent = obj[parentKey]
|
|
426
|
+
|
|
427
|
+
if (parent) {
|
|
428
|
+
delete parent[childKey]
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
310
432
|
private get updatedPackageJson() {
|
|
311
433
|
return {
|
|
312
434
|
...this.originalPackageJson,
|
|
@@ -325,7 +447,38 @@ export default prettierConfigNdx
|
|
|
325
447
|
bugs: {
|
|
326
448
|
url: `https://github.com/${this.gitNamespace}/${this.packageName}/issues`,
|
|
327
449
|
},
|
|
450
|
+
scripts: {
|
|
451
|
+
...(this.originalPackageJson.scripts ?? {}),
|
|
452
|
+
'build.ci': 'yarn run build.tsc && yarn run lint',
|
|
453
|
+
'build.dev':
|
|
454
|
+
'yarn run build.tsc --sourceMap ; yarn run lint ; prettier --write .',
|
|
455
|
+
'build.copy-files':
|
|
456
|
+
"mkdir -p build && rsync -avzq --exclude='*.ts' ./src/ ./build/",
|
|
457
|
+
'build.tsc': 'yarn run build.copy-files && tsc',
|
|
458
|
+
clean: 'yarn run clean.build',
|
|
459
|
+
'clean.all':
|
|
460
|
+
'yarn run clean.dependencies && yarn run clean.build',
|
|
461
|
+
'clean.build': 'rm -rf build/',
|
|
462
|
+
'clean.dependencies':
|
|
463
|
+
'rm -rf node_modules/ package-lock.json yarn.lock',
|
|
464
|
+
'fix.lint': "eslint --fix --cache '**/*.ts'",
|
|
465
|
+
lint: "eslint --cache '**/*.ts'",
|
|
466
|
+
rebuild:
|
|
467
|
+
'yarn run clean.all && yarn install && yarn run build.dev',
|
|
468
|
+
'update.dependencies': 'yarn run clean.dependencies && yarn',
|
|
469
|
+
test: 'NODE_OPTIONS=--experimental-vm-modules jest',
|
|
470
|
+
'watch.build.dev':
|
|
471
|
+
"tsc-watch --sourceMap --onCompilationComplete 'yarn run build.copy-files'",
|
|
472
|
+
},
|
|
328
473
|
dependencies: this.originalPackageJson.dependencies ?? {},
|
|
474
|
+
jest: {
|
|
475
|
+
...(this.originalPackageJson.jest ?? {}),
|
|
476
|
+
testEnvironment: 'node',
|
|
477
|
+
testRunner: 'jest-circus/runner',
|
|
478
|
+
testMatch: ['<rootDir>/build/__tests__/**/*.test.js?(x)'],
|
|
479
|
+
testTimeout: 5000,
|
|
480
|
+
maxWorkers: 4,
|
|
481
|
+
},
|
|
329
482
|
}
|
|
330
483
|
}
|
|
331
484
|
|
|
@@ -596,6 +749,8 @@ export default prettierConfigNdx
|
|
|
596
749
|
}
|
|
597
750
|
|
|
598
751
|
private async installDefaultDevDependencies() {
|
|
752
|
+
await this.removeDefaultDevDependencies()
|
|
753
|
+
|
|
599
754
|
const generateIdVersion = await this.getLatestVersion(
|
|
600
755
|
'@neurodevs/generate-id'
|
|
601
756
|
)
|
|
@@ -628,6 +783,15 @@ export default prettierConfigNdx
|
|
|
628
783
|
}
|
|
629
784
|
}
|
|
630
785
|
|
|
786
|
+
private async removeDefaultDevDependencies() {
|
|
787
|
+
console.log('Removing default devDependencies...')
|
|
788
|
+
|
|
789
|
+
await this.exec(
|
|
790
|
+
'yarn remove eslint eslint-config-spruce prettier chokidar-cli ts-node @types/node',
|
|
791
|
+
{ cwd: this.packageDir }
|
|
792
|
+
)
|
|
793
|
+
}
|
|
794
|
+
|
|
631
795
|
private async getLatestVersion(scopedPackageName: string) {
|
|
632
796
|
const { stdout } = await this.exec(
|
|
633
797
|
`yarn info ${scopedPackageName} version --silent`,
|
|
@@ -707,6 +871,22 @@ export default prettierConfigNdx
|
|
|
707
871
|
)
|
|
708
872
|
}
|
|
709
873
|
|
|
874
|
+
private async installEslintConfigFile() {
|
|
875
|
+
await this.removeOldEslintConfigMjs()
|
|
876
|
+
|
|
877
|
+
this.originalEslintConfig = await this.loadEslintConfigFile()
|
|
878
|
+
|
|
879
|
+
if (!this.eslintConfigIsUpToDate) {
|
|
880
|
+
console.log('Installing eslint.config.js...')
|
|
881
|
+
|
|
882
|
+
await this.writeFile(this.eslintConfigPath, this.eslintConfigFile, {
|
|
883
|
+
encoding: 'utf-8',
|
|
884
|
+
})
|
|
885
|
+
|
|
886
|
+
await this.commitInstallEslintConfigFile()
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
710
890
|
private async removeOldEslintConfigMjs() {
|
|
711
891
|
const fileExists = await this.pathExists(
|
|
712
892
|
path.join(this.packageDir, 'eslint.config.mjs')
|
|
@@ -721,21 +901,20 @@ export default prettierConfigNdx
|
|
|
721
901
|
}
|
|
722
902
|
}
|
|
723
903
|
|
|
724
|
-
private async
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if (!fileExists) {
|
|
729
|
-
console.log('Installing eslint.config.js...')
|
|
730
|
-
|
|
731
|
-
await this.writeFile(eslintConfigPath, this.eslintConfigFile, {
|
|
904
|
+
private async loadEslintConfigFile() {
|
|
905
|
+
try {
|
|
906
|
+
return await this.readFile(this.eslintConfigPath, {
|
|
732
907
|
encoding: 'utf-8',
|
|
733
908
|
})
|
|
734
|
-
|
|
735
|
-
|
|
909
|
+
} catch {
|
|
910
|
+
return ''
|
|
736
911
|
}
|
|
737
912
|
}
|
|
738
913
|
|
|
914
|
+
private get eslintConfigIsUpToDate() {
|
|
915
|
+
return this.originalEslintConfig.trim() === this.eslintConfigFile.trim()
|
|
916
|
+
}
|
|
917
|
+
|
|
739
918
|
private async commitInstallEslintConfigFile() {
|
|
740
919
|
await this.GitAutocommit(
|
|
741
920
|
`patch: install eslint.config.js (@neurodevs/meta-node: ${this.metaNodeVersion})`
|
|
@@ -743,30 +922,76 @@ export default prettierConfigNdx
|
|
|
743
922
|
}
|
|
744
923
|
|
|
745
924
|
private async installPrettierConfigFile() {
|
|
746
|
-
|
|
747
|
-
this.packageDir,
|
|
748
|
-
'prettier.config.js'
|
|
749
|
-
)
|
|
750
|
-
|
|
751
|
-
const fileExists = await this.pathExists(prettierConfigPath)
|
|
925
|
+
this.originalPrettierConfig = await this.loadPrettierConfigFile()
|
|
752
926
|
|
|
753
|
-
if (!
|
|
927
|
+
if (!this.prettierConfigIsUpToDate) {
|
|
754
928
|
console.log('Installing prettier.config.js...')
|
|
755
929
|
|
|
756
|
-
await this.writeFile(
|
|
757
|
-
|
|
758
|
-
|
|
930
|
+
await this.writeFile(
|
|
931
|
+
this.prettierConfigPath,
|
|
932
|
+
this.prettierConfigFile,
|
|
933
|
+
{
|
|
934
|
+
encoding: 'utf-8',
|
|
935
|
+
}
|
|
936
|
+
)
|
|
759
937
|
|
|
760
938
|
await this.commitInstallPrettierConfigFile()
|
|
761
939
|
}
|
|
762
940
|
}
|
|
763
941
|
|
|
942
|
+
private async loadPrettierConfigFile() {
|
|
943
|
+
try {
|
|
944
|
+
return await this.readFile(this.prettierConfigPath, {
|
|
945
|
+
encoding: 'utf-8',
|
|
946
|
+
})
|
|
947
|
+
} catch {
|
|
948
|
+
return ''
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
private get prettierConfigIsUpToDate() {
|
|
953
|
+
return (
|
|
954
|
+
this.originalPrettierConfig.trim() ===
|
|
955
|
+
this.prettierConfigFile.trim()
|
|
956
|
+
)
|
|
957
|
+
}
|
|
958
|
+
|
|
764
959
|
private async commitInstallPrettierConfigFile() {
|
|
765
960
|
await this.GitAutocommit(
|
|
766
961
|
`patch: install prettier.config.js (@neurodevs/meta-node: ${this.metaNodeVersion})`
|
|
767
962
|
)
|
|
768
963
|
}
|
|
769
964
|
|
|
965
|
+
private async installSettingsJsonFile() {
|
|
966
|
+
this.originalSettingsJson = await this.loadSettingsJsonFile()
|
|
967
|
+
|
|
968
|
+
if (!this.settingsJsonIsUpToDate) {
|
|
969
|
+
console.log('Installing .vscode/settings.json...')
|
|
970
|
+
|
|
971
|
+
await this.writeFile(this.settingsJsonPath, this.settingsJsonFile, {
|
|
972
|
+
encoding: 'utf-8',
|
|
973
|
+
})
|
|
974
|
+
|
|
975
|
+
await this.commitInstallSettingsJsonFile()
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
private async loadSettingsJsonFile() {
|
|
980
|
+
return await this.readFile(this.settingsJsonPath, {
|
|
981
|
+
encoding: 'utf-8',
|
|
982
|
+
})
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
private get settingsJsonIsUpToDate() {
|
|
986
|
+
return this.originalSettingsJson.trim() === this.settingsJsonFile.trim()
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
private async commitInstallSettingsJsonFile() {
|
|
990
|
+
await this.GitAutocommit(
|
|
991
|
+
`patch: install settings.json (@neurodevs/meta-node: ${this.metaNodeVersion})`
|
|
992
|
+
)
|
|
993
|
+
}
|
|
994
|
+
|
|
770
995
|
private async openVscode() {
|
|
771
996
|
if (this.shouldOpenVscode) {
|
|
772
997
|
await this.exec('code .', { cwd: this.packageDir })
|
package/tsconfig.json
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"./src/**/*.ts"
|
|
27
|
-
]
|
|
28
|
-
}
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "nodenext",
|
|
4
|
+
"moduleResolution": "nodenext",
|
|
5
|
+
"target": "ES2022",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"types": ["node"],
|
|
8
|
+
"baseUrl": "src",
|
|
9
|
+
"outDir": "build",
|
|
10
|
+
"sourceMap": false,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"noImplicitAny": true,
|
|
13
|
+
"noImplicitReturns": true,
|
|
14
|
+
"noUnusedLocals": true,
|
|
15
|
+
"forceConsistentCasingInFileNames": true,
|
|
16
|
+
"declaration": true,
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"esModuleInterop": true,
|
|
19
|
+
"moduleDetection": "force",
|
|
20
|
+
"allowJs": true,
|
|
21
|
+
"resolveJsonModule": true,
|
|
22
|
+
"experimentalDecorators": true
|
|
23
|
+
},
|
|
24
|
+
"include": ["./src/*.ts", "./src/**/*.ts"]
|
|
25
|
+
}
|
package/eslint.config.mjs
DELETED