agnostics 0.0.1

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.
Files changed (68) hide show
  1. package/README.md +3 -0
  2. package/lib/helpers/_Express.js +30 -0
  3. package/lib/helpers/_Parsers.js +73 -0
  4. package/lib/helpers/_Window.js +0 -0
  5. package/lib/helpers/_Yargs.js +328 -0
  6. package/lib/helpers/index.js +9 -0
  7. package/lib/index.js +11 -0
  8. package/lib/inputs/_Callers.js +122 -0
  9. package/lib/inputs/_Checker.js +3 -0
  10. package/lib/inputs/_Native.js +223 -0
  11. package/lib/inputs/_Types.js +112 -0
  12. package/lib/inputs/index.js +10 -0
  13. package/lib/logger/_ASCII.js +39 -0
  14. package/lib/logger/_Defs.js +55 -0
  15. package/lib/logger/_Logger.js +159 -0
  16. package/lib/logger/_Settings.js +52 -0
  17. package/lib/logger/_System.js +191 -0
  18. package/lib/logger/chars.js +730 -0
  19. package/lib/logger/index.js +5 -0
  20. package/lib/schema/_Schema.js +33 -0
  21. package/lib/schema/index.js +16 -0
  22. package/lib/specification/_Properties.js +144 -0
  23. package/lib/specification/index.js +9 -0
  24. package/package.json +32 -0
  25. package/types/helpers/_Express.d.ts +2 -0
  26. package/types/helpers/_Express.d.ts.map +1 -0
  27. package/types/helpers/_Parsers.d.ts +2 -0
  28. package/types/helpers/_Parsers.d.ts.map +1 -0
  29. package/types/helpers/_Window.d.ts +2 -0
  30. package/types/helpers/_Window.d.ts.map +1 -0
  31. package/types/helpers/_Yargs.d.ts +44 -0
  32. package/types/helpers/_Yargs.d.ts.map +1 -0
  33. package/types/helpers/index.d.ts +2 -0
  34. package/types/helpers/index.d.ts.map +1 -0
  35. package/types/index.d.ts +4 -0
  36. package/types/index.d.ts.map +1 -0
  37. package/types/inputs/_Callers.d.ts +14 -0
  38. package/types/inputs/_Callers.d.ts.map +1 -0
  39. package/types/inputs/_Checker.d.ts +2 -0
  40. package/types/inputs/_Checker.d.ts.map +1 -0
  41. package/types/inputs/_Native.d.ts +212 -0
  42. package/types/inputs/_Native.d.ts.map +1 -0
  43. package/types/inputs/_Types.d.ts +34 -0
  44. package/types/inputs/_Types.d.ts.map +1 -0
  45. package/types/inputs/index.d.ts +3 -0
  46. package/types/inputs/index.d.ts.map +1 -0
  47. package/types/logger/_ASCII.d.ts +2 -0
  48. package/types/logger/_ASCII.d.ts.map +1 -0
  49. package/types/logger/_Defs.d.ts +54 -0
  50. package/types/logger/_Defs.d.ts.map +1 -0
  51. package/types/logger/_Logger.d.ts +5 -0
  52. package/types/logger/_Logger.d.ts.map +1 -0
  53. package/types/logger/_Settings.d.ts +24 -0
  54. package/types/logger/_Settings.d.ts.map +1 -0
  55. package/types/logger/_System.d.ts +10 -0
  56. package/types/logger/_System.d.ts.map +1 -0
  57. package/types/logger/chars.d.ts +93 -0
  58. package/types/logger/chars.d.ts.map +1 -0
  59. package/types/logger/index.d.ts +6 -0
  60. package/types/logger/index.d.ts.map +1 -0
  61. package/types/schema/_Schema.d.ts +11 -0
  62. package/types/schema/_Schema.d.ts.map +1 -0
  63. package/types/schema/index.d.ts +3 -0
  64. package/types/schema/index.d.ts.map +1 -0
  65. package/types/specification/_Properties.d.ts +158 -0
  66. package/types/specification/_Properties.d.ts.map +1 -0
  67. package/types/specification/index.d.ts +2 -0
  68. package/types/specification/index.d.ts.map +1 -0
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Agnostics
2
+
3
+ ![agnostics](./diogenes.jpg)
@@ -0,0 +1,30 @@
1
+
2
+ // eventually API structure
3
+
4
+ /*
5
+
6
+ easy peasy
7
+
8
+ /helloworld
9
+ /foo
10
+ /foo/:id/bar
11
+ /foo/:id/bar/:name
12
+ /foo/list
13
+ /foo/list/:offset
14
+ /foo/list/:offset/really/:deep/thing/:right/here
15
+ /foo/list/:offset/really/:deep/thing/:right/here/:ooooh
16
+
17
+ .scriptName('api')
18
+ .command('helloworld')
19
+ .command('foo <id> bar [name]')
20
+ .command('foo')
21
+ .command('foo list [offset]')
22
+ .command('foo list <offset> really <deep> thing <right> here [ooooh]')
23
+
24
+
25
+ RULES: last one is always optional (to avoid conflicts)
26
+
27
+
28
+
29
+
30
+ */
@@ -0,0 +1,73 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // PARSING //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ // --------- MIME BUCKETS ---------
10
+
11
+ const BUCKETS = {
12
+ image: ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'bmp', 'ico'],
13
+ video: ['mp4', 'webm', 'ogg', 'mov', 'avi', 'mkv'],
14
+ audio: ['mp3', 'wav', 'ogg', 'flac', 'aac', 'm4a'],
15
+ text: ['txt', 'md', 'csv', 'html', 'css', 'js', 'json'],
16
+ font: ['woff', 'woff2', 'ttf', 'otf'],
17
+ application: ['pdf', 'zip', 'json', 'xml']
18
+ }
19
+
20
+ // --------- ALIASES ---------
21
+
22
+ const ALIASES = {
23
+ 'jpg': 'jpeg',
24
+ 'jpeg': 'jpg',
25
+ 'm4a': 'mp4',
26
+ 'mp4': 'm4a',
27
+ 'tif': 'tiff',
28
+ 'tiff': 'tif'
29
+ }
30
+
31
+ export const NormaliseAccept = (input) => {
32
+ if (!input) return []
33
+
34
+ const raw = Array.isArray(input) ? input : input.split(/[,\s]+/)
35
+ const extensions = new Set()
36
+
37
+ raw
38
+ .map(item => item.trim().toLowerCase())
39
+ .filter(Boolean)
40
+ .forEach(item => {
41
+ let current = []
42
+
43
+ // 1. Handle Wildcards (e.g., image/*)
44
+ if (item.includes('/*') || (item.includes('/') && item.endsWith('/'))) {
45
+ const cat = item.split('/')[0]
46
+ if (BUCKETS[cat]) current.push(...BUCKETS[cat])
47
+ }
48
+
49
+ // 2. Handle Specific Mimes (e.g., image/png -> png)
50
+ else if (item.includes('/')) {
51
+ current.push(item.split('/').pop())
52
+ }
53
+
54
+ // 3. Handle Extensions (e.g., .jpg -> jpg)
55
+ else if (item.includes('.')) {
56
+ current.push(item.split('.').pop())
57
+ }
58
+
59
+ // 4. Fallback (e.g., "png")
60
+ else {
61
+ current.push(item)
62
+ }
63
+
64
+ // FINAL PASS: add found items + their aliases to the Set
65
+
66
+ current.forEach(ext => {
67
+ extensions.add(ext)
68
+ if (ALIASES[ext]) extensions.add(ALIASES[ext])
69
+ })
70
+ })
71
+
72
+ return Array.from(extensions)
73
+ }
File without changes
@@ -0,0 +1,328 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // YARGS //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ import { Obj, isArr, isNum, isBool } from '../inputs/index.js'
10
+ import { NormaliseAccept } from './_Parsers.js'
11
+
12
+ import { CreateLogger } from '../logger/index.js'
13
+ const { SAY, ERR, HMM, HUH } = CreateLogger( import.meta.url )
14
+
15
+
16
+ async function LoadYargs() {
17
+
18
+ if (!globalThis.yargsLib || !globalThis.yargsHideBin) {
19
+ try {
20
+ globalThis.yargsLib = (await import ('yargs')).default
21
+ globalThis.yargsHideBin = (await import ('yargs/helpers')).hideBin
22
+ return true
23
+ } catch(err) {
24
+ return ERR(`YARGS UNAVAILABLE`, err)
25
+ }
26
+ }
27
+ }
28
+
29
+ async function LoadGlobby() {
30
+
31
+ if (!globalThis.globbyLib || !globalThis.pathExtname) {
32
+ try {
33
+ globalThis.globbyLib = (await import ('globby')).globby
34
+ globalThis.pathExtname = (await import ('path')).extname
35
+ return true
36
+ } catch(err) {
37
+ return ERR(`GLOBS UNAVAILABLE`, err)
38
+ }
39
+ }
40
+ }
41
+
42
+ async function GetYargsFiles( value, extensions ) {
43
+
44
+ try {
45
+
46
+ if (!(await LoadGlobby())) return []
47
+
48
+
49
+ const anything = (extensions.length === 0 || extensions.includes('*'))
50
+
51
+ const found = await globalThis.globbyLib(value, {
52
+ onlyFiles: true,
53
+ expandDirectories: false,
54
+ caseSensitiveMatch: false
55
+ })
56
+
57
+ const exts = extensions.map( ext => ext.toLowerCase().replaceAll('.',''))
58
+ const files = anything ? found : found.filter(file => {
59
+ const ext = globalThis.pathExtname(file).replaceAll('.','')
60
+ return exts.includes(ext)
61
+ })
62
+
63
+ if (files.length === 0) ERR('NO FILES', value)
64
+
65
+ return files
66
+
67
+ } catch (err) {
68
+ ERR('FILES ERROR:', err.message)
69
+ return []
70
+ }
71
+ }
72
+
73
+ export function GetYargsType( type ) {
74
+ if (isNum(type)) return 'number'
75
+ if (isBool(type)) return 'boolean'
76
+ return 'string'
77
+ }
78
+
79
+
80
+ export function GetParsedYargsOptions( agOptions, aliasStore = [] ) {
81
+
82
+ const options = {}
83
+
84
+ for (const [key, def] of Object.entries( agOptions )) {
85
+
86
+ const label = def?.label || key
87
+ let alias = label[0]
88
+ let counter = 1
89
+
90
+ while (aliasStore.includes(alias) && counter < 4) {
91
+ alias = label.substring(0,counter++)
92
+ }
93
+
94
+ if (aliasStore.includes(alias)) {
95
+ HMM('CANNOT GENERATE ALIAS FOR:', key)
96
+ alias = null
97
+ } else {
98
+ aliasStore.push(alias)
99
+ }
100
+
101
+ options[key] = ConvertYargsProperty( def, {
102
+ alias: alias,
103
+ demandOption: def.required || false,
104
+ })
105
+ }
106
+
107
+ return options
108
+ }
109
+
110
+ export function ConvertYargsProperty( def, override = {} ) {
111
+
112
+ const array = def.gui == 'files' || isArr(def.type)
113
+
114
+ return Object.assign({
115
+ array,
116
+ describe: def.description,
117
+ type: GetYargsType(def.type),
118
+ coerce: def.oncheck,
119
+ default: def.default,
120
+ accept: NormaliseAccept( def.accept )
121
+ }, override)
122
+ }
123
+
124
+
125
+ export function YargsProcessWorkaround() {
126
+
127
+ // YARGS HACK (MINIMUM POSITIONAL ARGUMENTS)
128
+
129
+ let index = process.argv.length
130
+ for (let i = 0; i < process.argv.length; i++) {
131
+ const arg = process.argv[i]
132
+ if (arg.startsWith('--')) index = i
133
+ }
134
+ process.argv.splice(index, 0, 'run')
135
+ }
136
+
137
+ export class YargsCommand {
138
+
139
+ command = '$0'
140
+ description = 'N/A'
141
+ version = 'N/A'
142
+ positionals = {}
143
+ options = {}
144
+
145
+ $positionals = {}
146
+ $options = {}
147
+ $aliasStore = []
148
+
149
+ constructor( { positionals, options = {}, description = 'N/A', version = 'N/A' } ) {
150
+
151
+
152
+ this.description = description
153
+ this.version = version
154
+
155
+ // --------- OPTIONS ---------
156
+
157
+ this.$options = Obj( options ).properties
158
+ this.options = GetParsedYargsOptions( this.$options, this.$aliasStore )
159
+
160
+ // --------- POSITIONALS ---------
161
+
162
+ this.$positionals = Obj( positionals ).properties
163
+ const posKeys = Object.keys( this.$positionals )
164
+ const strArray = []
165
+
166
+ for (let i = 0; i < posKeys.length; i++) {
167
+
168
+ const key = posKeys[i]
169
+ const def = this.$positionals[key]
170
+
171
+ const array = def.gui == 'files' || isArr(def.type)
172
+ const required = i < posKeys.length - 1 || def.required
173
+
174
+ strArray.push( required ? '<' : '[' )
175
+ strArray.push( key )
176
+ if (array) strArray.push( '..' )
177
+ strArray.push( required ? '>' : ']' )
178
+ strArray.push( ' ' )
179
+
180
+ this.positionals[key] = ConvertYargsProperty( def, {
181
+ array: array,
182
+ demandOption: required,
183
+ })
184
+ }
185
+
186
+ this.command = strArray.join('')
187
+
188
+ }
189
+
190
+ async run( runCallback = async yargsData => {} ) {
191
+
192
+ if (!(await LoadYargs())) return
193
+
194
+ YargsProcessWorkaround()
195
+
196
+ const args = globalThis.yargsHideBin( process.argv )
197
+ const instance = globalThis.yargsLib( args )
198
+
199
+ instance.command(
200
+ this.command,
201
+ this.description,
202
+ yargsData => {
203
+ const positionals = Object.entries(this.positionals)
204
+ for (const [key, def] of positionals) {
205
+ yargsData.positional(key, def)
206
+ }
207
+ },
208
+ async yargsData => {
209
+
210
+ const lookup = ['positionals']
211
+ for (const id of lookup) {
212
+ const keys = Object.keys(this[id])
213
+ for (const key of keys) {
214
+ const def = this[id][key]
215
+ if (def.array && yargsData[key]) {
216
+ yargsData[key] = await GetYargsFiles( yargsData[key], def.accept )
217
+ }
218
+ }
219
+ }
220
+
221
+ await runCallback( yargsData )
222
+
223
+ }
224
+ )
225
+
226
+ if (this.options) instance.options(this.options)
227
+
228
+ instance.strict()
229
+ instance.recommendCommands()
230
+
231
+ instance.help()
232
+ instance.alias('h', 'help')
233
+ instance.version(this.version)
234
+
235
+ return await instance.parse()
236
+
237
+ }
238
+ }
239
+
240
+
241
+ export class YargsCLI {
242
+
243
+ options = null
244
+ description = 'N/A'
245
+ version = 'N/A'
246
+
247
+ $aliasStore = []
248
+ $options = {}
249
+ $commands = {}
250
+
251
+ constructor( { commands, options = {}, description = 'N/A', version = 'N/A' } ) {
252
+
253
+ if (typeof commands != 'object') throw Error('no commands defined')
254
+ if (!description) HMM('no description defined (recommended)')
255
+ if (!version) HMM('no version defined (recommended)')
256
+
257
+ this.description = description
258
+ this.version = version
259
+
260
+ // --------- OPTIONS ---------
261
+
262
+ this.$options = Obj( options ).properties
263
+ this.options = GetParsedYargsOptions( this.$options, this.$aliasStore )
264
+
265
+ // --------- COMMANDS ---------
266
+
267
+ this.$commands = commands
268
+
269
+ }
270
+
271
+ async run( runCallback = async (cmdKey, yargsData) => {} ) {
272
+
273
+ if (!(await LoadYargs())) return
274
+
275
+ // YargsProcessWorkaround()
276
+
277
+
278
+ const args = globalThis.yargsHideBin( process.argv )
279
+ const instance = globalThis.yargsLib( args )
280
+
281
+ for (const [cmdKey, cmdObj] of Object.entries(this.$commands)) {
282
+
283
+ instance.command(
284
+ `${cmdKey} ${cmdObj.command}`.trim(),
285
+ cmdObj.description,
286
+ yargsData => {
287
+ const positionals = Object.entries(cmdObj.positionals)
288
+ for (const [key, def] of positionals) yargsData.positional(key, def)
289
+ const options = Object.entries(cmdObj.options)
290
+ for (const [key, def] of options) yargsData.option(key, def)
291
+ },
292
+ async yargsData => {
293
+
294
+ const lookup = [ cmdObj.positionals ]
295
+
296
+ for (const obj of lookup) {
297
+ const keys = Object.keys(obj)
298
+ for (const key of keys) {
299
+ const def = obj[key]
300
+ if (def.array && yargsData[key]) {
301
+ yargsData[key] = await GetYargsFiles( yargsData[key], def.accept )
302
+ }
303
+ }
304
+ }
305
+
306
+ await runCallback( cmdKey, yargsData )
307
+
308
+ })
309
+ }
310
+
311
+ if (this.options) instance.options(this.options)
312
+
313
+ instance.demandCommand(1, 'You must provide a valid command')
314
+ instance.strict()
315
+ instance.recommendCommands()
316
+
317
+ instance.help()
318
+ instance.alias('h', 'help')
319
+ instance.version(this.version)
320
+
321
+ return await instance.parse()
322
+ }
323
+
324
+
325
+ }
326
+
327
+
328
+
@@ -0,0 +1,9 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // HELPERS //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ export * from './_Yargs.js'
package/lib/index.js ADDED
@@ -0,0 +1,11 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // AGNOSTIC //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ export * from './helpers/index.js'
10
+ export * from './inputs/index.js'
11
+ export * from './specification/index.js'
@@ -0,0 +1,122 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // CALLER //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ import { Properties } from './../specification/index.js'
10
+
11
+ const META_PROPS = ['options', 'config', 'extra', 'custom', 'props']
12
+
13
+ export function Caller( data ) {
14
+
15
+ let output = {}
16
+
17
+ const WriteProp = (key, value, otherKey) => {
18
+ if (output[key] != null) {
19
+ if (!output.misc) output.misc = {}
20
+ output.misc[otherKey || key] = value
21
+ } else {
22
+ output[key] = value
23
+ }
24
+ }
25
+
26
+ const AddProp = ( inputKey, inputValue ) => {
27
+
28
+ for (const [outputKey, spec] of Object.entries(Properties)) {
29
+ if (inputKey == outputKey) {
30
+ WriteProp( outputKey, inputValue )
31
+ continue
32
+ } else {
33
+ for (const otherKey of [outputKey, ...(spec.keys || [])]) {
34
+ if (inputKey.includes(otherKey.replace(/[_-]/g, ''))) {
35
+ WriteProp( outputKey, inputValue, otherKey )
36
+ continue
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ const ExtractProps = ( data ) => {
44
+
45
+ for (let [key,value] of Object.entries(data)) {
46
+
47
+ key = key.toLowerCase() // controversial
48
+
49
+ // SPLIT FOR OPTIONS
50
+
51
+ if (key.includes(':')) {
52
+ const [sub1, sub2] = key.split(':')
53
+ AddProp(sub2, value)
54
+ }
55
+
56
+ // SEARCH FOR OPTIONS
57
+
58
+ for (const name of META_PROPS) {
59
+ if (key.includes(name) && typeof value == 'object') {
60
+ ExtractProps(value)
61
+ continue
62
+ }
63
+ }
64
+
65
+ if (value != null) AddProp( key,value )
66
+
67
+ }
68
+ }
69
+
70
+ ExtractProps( data )
71
+
72
+ return data
73
+ }
74
+
75
+ //////////////////////////////////////////
76
+ // //
77
+ // //
78
+ // TYPE CALLERS //
79
+ // //
80
+ // //
81
+ //////////////////////////////////////////
82
+
83
+
84
+ /** @type {typeof MinMaxCaller} */
85
+ export function MinMaxCaller( value, min, max, schema ) {
86
+ const property = Caller({ ...schema, default: value, min, max })
87
+ return property
88
+ }
89
+
90
+ /** @type {typeof DefaultCaller} */
91
+ export function DefaultCaller( value, schema ) {
92
+ const property = Caller({ ...schema, default: value })
93
+ return property
94
+ }
95
+
96
+ /** @type {typeof EnumCaller} */
97
+ export function EnumCaller( value, enumOptions, schema ) {
98
+ return Caller( {...schema, default: value, enum: enumOptions } )
99
+ }
100
+
101
+ /** @type {typeof ObjCaller} */
102
+ export function ObjCaller( properties, schema) {
103
+ const objProperty = Caller({ ...schema, properties })
104
+ let index = 0
105
+ for (let [key,prop] of Object.entries(objProperty.properties)) {
106
+ prop.key = key
107
+ prop.index = index++
108
+ }
109
+ return objProperty
110
+ }
111
+
112
+ /** @type {typeof ArrCaller} */
113
+ export function ArrCaller(value, items, schema) {
114
+ const arrProperty = Caller({ ...schema, default: value, items })
115
+ return arrProperty
116
+ }
117
+
118
+ /** @type {typeof EventCaller} */
119
+ export function EventCaller( event, schema ) {
120
+ const eventProperty = Caller({ ...schema, onupdate: event })
121
+ return eventProperty
122
+ }
@@ -0,0 +1,3 @@
1
+
2
+
3
+ // something here for actual type checker, if adding express stuff, use safety lib