@jondotsoy/don 0.0.2 → 0.0.4
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/README.md +38 -368
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1,32 +1,39 @@
|
|
|
1
1
|
# DON: Directive Object Notation
|
|
2
2
|
|
|
3
|
-
DON
|
|
3
|
+
DON is a human-readable data serialization format designed around the concept of directives and subdirectives. It combines the simplicity of declarative syntax with the flexibility of nested structures, allowing you to define hierarchical configurations using intuitive directive blocks. Each directive can accept arguments and contain nested subdirectives, making it ideal for configuration files, infrastructure definitions, and structured data representation where readability and expressiveness are priorities.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
7
|
+
- **Minimal Syntax**: Fewer special characters, more readability
|
|
8
|
+
- **Sequential Processing**: Directives are processed as a pipeline, allowing overwriting and incremental composition
|
|
9
|
+
- **Flexible Nesting**: Supports hierarchies of any depth
|
|
10
|
+
- **Multiple Data Types**: Keywords, strings, numbers, booleans, and null
|
|
11
|
+
- **Heredoc Support**: Multi-line content blocks for embedded scripts and text
|
|
12
|
+
- **Comments**: Supports line comments (`//`, `#`) and multi-line comments (`/* */`)
|
|
13
|
+
- **Unambiguous**: Clear parsing rules and delimitation
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### Using npm
|
|
15
18
|
|
|
16
19
|
```bash
|
|
17
20
|
npm install @jondotsoy/don
|
|
18
21
|
```
|
|
19
22
|
|
|
23
|
+
### Using Bun
|
|
24
|
+
|
|
20
25
|
```bash
|
|
21
26
|
bun add @jondotsoy/don
|
|
22
27
|
```
|
|
23
28
|
|
|
24
|
-
##
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Basic Example
|
|
25
32
|
|
|
26
33
|
```typescript
|
|
27
34
|
import { DocumentEncoder, LexerEncoder } from "@jondotsoy/don";
|
|
28
35
|
|
|
29
|
-
//
|
|
36
|
+
// Parse a DON document
|
|
30
37
|
const source = `
|
|
31
38
|
name "my-app"
|
|
32
39
|
version 1.0.0
|
|
@@ -36,381 +43,44 @@ container {
|
|
|
36
43
|
}
|
|
37
44
|
`;
|
|
38
45
|
|
|
39
|
-
const lexer = new LexerEncoder();
|
|
40
|
-
const tokens = lexer.encode(source);
|
|
41
|
-
|
|
42
46
|
const document = new DocumentEncoder();
|
|
43
|
-
const directives = document.encode(
|
|
47
|
+
const directives = document.encode(source);
|
|
44
48
|
|
|
45
49
|
console.log(directives);
|
|
46
50
|
```
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
### Estructura de una Directiva
|
|
51
|
-
|
|
52
|
-
Una directiva tiene la siguiente estructura:
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
<nombre> [argumentos...] [{ subdirectivas }]
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
**Componentes:**
|
|
59
|
-
|
|
60
|
-
- **Nombre**: Identificador de la directiva (keyword, string, number o boolean)
|
|
61
|
-
- **Argumentos**: Cero o más valores separados por espacios
|
|
62
|
-
- **Bloque**: Opcional, contiene subdirectivas entre llaves `{ }`
|
|
63
|
-
|
|
64
|
-
### Ejemplos
|
|
65
|
-
|
|
66
|
-
**Directivas simples:**
|
|
67
|
-
|
|
68
|
-
```don
|
|
69
|
-
name "my-app"
|
|
70
|
-
version 1.0.0
|
|
71
|
-
enabled true
|
|
72
|
-
port 8080
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**Directivas con bloques:**
|
|
52
|
+
### Using the Inspect Utility
|
|
76
53
|
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
port 8080
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**Directivas con argumentos y bloques:**
|
|
54
|
+
```typescript
|
|
55
|
+
import { DocumentEncoder, LexerEncoder } from "@jondotsoy/don";
|
|
56
|
+
import { inspect } from "@jondotsoy/don/utils";
|
|
85
57
|
|
|
86
|
-
|
|
58
|
+
const source = `
|
|
87
59
|
service "web" replicas 3 {
|
|
88
60
|
container "nginx" {
|
|
89
61
|
port 80
|
|
90
62
|
image "nginx:latest"
|
|
91
63
|
}
|
|
92
64
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
**Directivas repetidas:**
|
|
96
|
-
|
|
97
|
-
```don
|
|
98
|
-
container {
|
|
99
|
-
image "nginx"
|
|
100
|
-
port 80
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
container {
|
|
104
|
-
image "redis"
|
|
105
|
-
port 6379
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## Tipos de Datos
|
|
110
|
-
|
|
111
|
-
DON reconoce los siguientes tipos de tokens:
|
|
112
|
-
|
|
113
|
-
- **Keywords**: Identificadores que comienzan con letra o guion bajo (`name`, `version`, `container`)
|
|
114
|
-
- **Strings**: Cadenas de texto entre comillas dobles o simples (`"texto"`, `'texto'`)
|
|
115
|
-
- Soportan caracteres escapados: `\"`, `\'`, `\\`
|
|
116
|
-
- **Numbers**: Enteros o decimales (`123`, `45.67`)
|
|
117
|
-
- Pueden incluir guiones bajos como separadores: `1_000_000`
|
|
118
|
-
- **Booleans**: Valores `true` o `false`
|
|
119
|
-
- **Null**: Valor nulo `null`
|
|
120
|
-
- **Punctuators**: Símbolos delimitadores: `{`, `}`, `[`, `]`, `,`, `+`, `-`, `/`, `*`, `<`, `>`
|
|
121
|
-
- **Comments**:
|
|
122
|
-
- Línea: `// comentario` o `# comentario`
|
|
123
|
-
- Multilínea: `/* comentario */`
|
|
124
|
-
|
|
125
|
-
## Reglas de Sintaxis
|
|
126
|
-
|
|
127
|
-
1. **Nombre de directiva**: Puede ser un keyword, string, number o boolean
|
|
128
|
-
2. **Argumentos**: Cero o más tokens separados por espacios
|
|
129
|
-
3. **Bloque de subdirectivas**: Opcional, delimitado por llaves `{ }`
|
|
130
|
-
4. **Delimitación**: Las directivas se separan por saltos de línea
|
|
131
|
-
5. **Anidación**: Las subdirectivas siguen las mismas reglas
|
|
132
|
-
6. **Restricción**: No puede haber tokens después de un bloque en la misma línea
|
|
133
|
-
|
|
134
|
-
**Sintaxis válida:**
|
|
135
|
-
|
|
136
|
-
```don
|
|
137
|
-
// Directiva simple
|
|
138
|
-
name "my-app"
|
|
139
|
-
version 1.0.0
|
|
140
|
-
|
|
141
|
-
// Directiva con bloque
|
|
142
|
-
container {
|
|
143
|
-
image "nginx"
|
|
144
|
-
port 8080
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Comentarios
|
|
148
|
-
# Comentario de línea
|
|
149
|
-
/* Comentario multilínea */
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
**Sintaxis inválida:**
|
|
153
|
-
|
|
154
|
-
```don
|
|
155
|
-
// ❌ Tokens después del bloque
|
|
156
|
-
container { image "nginx" } extra
|
|
157
|
-
|
|
158
|
-
// ❌ String sin cerrar
|
|
159
|
-
name "unclosed
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
## Casos de Uso
|
|
163
|
-
|
|
164
|
-
### Archivos de Configuración
|
|
165
|
-
|
|
166
|
-
```don
|
|
167
|
-
app "my-service" {
|
|
168
|
-
version 2.1.0
|
|
169
|
-
environment "production"
|
|
170
|
-
|
|
171
|
-
database {
|
|
172
|
-
host "localhost"
|
|
173
|
-
port 5432
|
|
174
|
-
name "mydb"
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
cache {
|
|
178
|
-
enabled true
|
|
179
|
-
ttl 3600
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Definiciones de Infraestructura (Kubernetes)
|
|
185
|
-
|
|
186
|
-
```yaml
|
|
187
|
-
apiVersion: v1
|
|
188
|
-
kind: Pod
|
|
189
|
-
metadata:
|
|
190
|
-
name: command-demo
|
|
191
|
-
labels:
|
|
192
|
-
purpose: demonstrate-command
|
|
193
|
-
spec:
|
|
194
|
-
containers:
|
|
195
|
-
- name: command-demo-container
|
|
196
|
-
image: debian
|
|
197
|
-
command: ["printenv"]
|
|
198
|
-
args: ["HOSTNAME", "KUBERNETES_PORT"]
|
|
199
|
-
restartPolicy: OnFailure
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
```don
|
|
203
|
-
apiVersion v1 {
|
|
204
|
-
pod {
|
|
205
|
-
metadata {
|
|
206
|
-
name "command-demo"
|
|
207
|
-
labels {
|
|
208
|
-
purpose "demonstrate-command"
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
spec {
|
|
212
|
-
restartPolicy "OnFailure"
|
|
213
|
-
container debian "command-demo-container" {
|
|
214
|
-
command printenv HOSTNAME KUBERNETES_PORT
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### Schemas de Datos
|
|
222
|
-
|
|
223
|
-
```don
|
|
224
|
-
schema "user" {
|
|
225
|
-
id integer primaryKey autoIncrement
|
|
226
|
-
email string unique required
|
|
227
|
-
name string required
|
|
228
|
-
createdAt timestamp default now
|
|
229
|
-
}
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### Reglas de Seguridad (Firebase)
|
|
233
|
-
|
|
234
|
-
```don
|
|
235
|
-
service "firebase.storage" {
|
|
236
|
-
match "/b/{bucket}/o" {
|
|
237
|
-
match "/someFolder/{fileName}" {
|
|
238
|
-
allow read write {
|
|
239
|
-
if "request.auth" "!=" null
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### Servicios con Múltiples Contenedores
|
|
247
|
-
|
|
248
|
-
```don
|
|
249
|
-
service "my-service" {
|
|
250
|
-
replicas 2
|
|
251
|
-
container {
|
|
252
|
-
image "my-image"
|
|
253
|
-
port 8080
|
|
254
|
-
}
|
|
255
|
-
container {
|
|
256
|
-
image "my-other-image"
|
|
257
|
-
port 8081
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
## Equivalencias con JSON
|
|
263
|
-
|
|
264
|
-
DON ofrece una sintaxis más limpia y legible para representar estructuras de datos comunes en JSON:
|
|
265
|
-
|
|
266
|
-
**Propiedades simples:**
|
|
267
|
-
|
|
268
|
-
- `{"name":"foo"}` → `name "foo"`
|
|
269
|
-
- `{"version":1}` → `version 1`
|
|
270
|
-
- `{"private": true}` → `private true`
|
|
271
|
-
|
|
272
|
-
**Objetos anidados:**
|
|
273
|
-
|
|
274
|
-
```json
|
|
275
|
-
{ "name": "foo", "meta": { "format": "json", "version": 1 } }
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
```don
|
|
279
|
-
name "foo"
|
|
280
|
-
meta {
|
|
281
|
-
format "json"
|
|
282
|
-
version 1
|
|
283
|
-
}
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
**Arrays o Listas:**
|
|
287
|
-
|
|
288
|
-
```json
|
|
289
|
-
{ "icons": ["foo", "taz"] }
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
```don
|
|
293
|
-
icons {
|
|
294
|
-
icon "foo"
|
|
295
|
-
icon "taz"
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## Equivalencias con YAML
|
|
300
|
-
|
|
301
|
-
DON puede representar estructuras YAML de manera más concisa. Los tags de YAML (como `!!date`, `!!str`, `!!int`) se convierten en nombres de directivas en DON:
|
|
302
|
-
|
|
303
|
-
**Tags de tipo:**
|
|
304
|
-
|
|
305
|
-
```yaml
|
|
306
|
-
---
|
|
307
|
-
createdAt: !!date 2002-04-28
|
|
308
|
-
count: !!int 42
|
|
309
|
-
description: !!str "Hello World"
|
|
310
|
-
enabled: !!bool true
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
```don
|
|
314
|
-
createdAt date "2002-04-28"
|
|
315
|
-
count int 42
|
|
316
|
-
description str "Hello World"
|
|
317
|
-
enabled bool true
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
**Objetos anidados con tags:**
|
|
321
|
-
|
|
322
|
-
```yaml
|
|
323
|
-
---
|
|
324
|
-
metadata:
|
|
325
|
-
createdAt: !!date 2002-04-28
|
|
326
|
-
version: !!int 1
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
```don
|
|
330
|
-
metadata {
|
|
331
|
-
createdAt date "2002-04-28"
|
|
332
|
-
version int 1
|
|
333
|
-
}
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
## Inspiración
|
|
337
|
-
|
|
338
|
-
DON toma inspiración de la sintaxis de Python para el paso de argumentos, permitiendo tanto argumentos posicionales como argumentos con nombre:
|
|
339
|
-
|
|
340
|
-
```python
|
|
341
|
-
# Python - Argumentos posicionales
|
|
342
|
-
print("foo")
|
|
343
|
-
|
|
344
|
-
# Python - Argumentos con nombre
|
|
345
|
-
dict(name="foo")
|
|
346
|
-
|
|
347
|
-
# Python - Combinación
|
|
348
|
-
Container("nginx", replicas=3, port=80)
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
```don
|
|
352
|
-
# DON - Argumentos posicionales
|
|
353
|
-
print "foo"
|
|
354
|
-
|
|
355
|
-
# DON - Argumentos con nombre (mediante subdirectivas)
|
|
356
|
-
dict {
|
|
357
|
-
name "foo"
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
# DON - Combinación
|
|
361
|
-
Container "nginx" {
|
|
362
|
-
replicas 3
|
|
363
|
-
port 80
|
|
364
|
-
}
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
## Desarrollo
|
|
368
|
-
|
|
369
|
-
### Scripts Disponibles
|
|
370
|
-
|
|
371
|
-
```bash
|
|
372
|
-
# Compilar el proyecto
|
|
373
|
-
npm run build
|
|
374
|
-
|
|
375
|
-
# Limpiar archivos compilados
|
|
376
|
-
npm run clean
|
|
377
|
-
|
|
378
|
-
# Formatear código
|
|
379
|
-
npm run fmt
|
|
380
|
-
|
|
381
|
-
# Verificar formato
|
|
382
|
-
npm run lint
|
|
383
|
-
```
|
|
65
|
+
`;
|
|
384
66
|
|
|
385
|
-
|
|
67
|
+
const doc = new DocumentEncoder().encode(source);
|
|
386
68
|
|
|
69
|
+
// Pretty-print the parsed document structure
|
|
70
|
+
console.log(inspect(doc));
|
|
387
71
|
```
|
|
388
|
-
.
|
|
389
|
-
├── src/ # Código fuente TypeScript
|
|
390
|
-
│ ├── lexer.ts # Analizador léxico
|
|
391
|
-
│ ├── document.ts # Parser de documentos
|
|
392
|
-
│ ├── chunk.ts # Manejo de chunks
|
|
393
|
-
│ └── utils/ # Utilidades
|
|
394
|
-
├── lib/ # Código compilado
|
|
395
|
-
│ └── esm/ # Módulos ES
|
|
396
|
-
├── docs/ # Documentación
|
|
397
|
-
└── index.ts # Punto de entrada
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
## Documentación
|
|
401
|
-
|
|
402
|
-
Para más información sobre DON, consulta la [documentación completa](./docs/index.md):
|
|
403
72
|
|
|
404
|
-
|
|
405
|
-
- [Directivas](./docs/concepts/directive.md): Anatomía y uso de directivas
|
|
406
|
-
- [Heredocs](./docs/concepts/heredoc.md): Contenido multilínea
|
|
407
|
-
- [Tipos de Datos](./docs/concepts/types/): Especificación de tipos soportados
|
|
408
|
-
- [Inspiración](./docs/inspiration.md): Objetivos y visión del proyecto
|
|
73
|
+
## Documentation
|
|
409
74
|
|
|
410
|
-
|
|
75
|
+
For more information about DON, check out the [complete documentation](./docs/index.md):
|
|
411
76
|
|
|
412
|
-
|
|
77
|
+
- [DON File Format](./docs/don-file.md): Complete format specification
|
|
78
|
+
- [Formal Specification v0](./docs/specs/v0/spec.md): Draft specification (v0)
|
|
79
|
+
- [Directives](./docs/concepts/directive.md): Anatomy and usage of directives
|
|
80
|
+
- [Heredocs](./docs/concepts/heredoc.md): Multi-line content blocks
|
|
81
|
+
- [Data Types](./docs/concepts/types/): Specification of supported types
|
|
82
|
+
- [Inspiration](./docs/inspiration.md): Project goals and vision
|
|
413
83
|
|
|
414
|
-
##
|
|
84
|
+
## License
|
|
415
85
|
|
|
416
|
-
[
|
|
86
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jondotsoy/don",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "DON (Directive Object Notation) - A human-readable data serialization format based on directives and subdirectives for configuration files, infrastructure definitions, and structured data",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"don",
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
".": {
|
|
27
27
|
"types": "./lib/esm/index.d.ts",
|
|
28
28
|
"import": "./lib/esm/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./utils": {
|
|
31
|
+
"types": "./lib/esm/utils/inspect.d.ts",
|
|
32
|
+
"import": "./lib/esm/utils/inspect.js"
|
|
29
33
|
}
|
|
30
34
|
},
|
|
31
35
|
"files": [
|