@paris-ias/trees 2.0.1 → 2.0.2
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/dist/form/actions.d.ts +1 -129
- package/dist/form/actions.js +17 -2
- package/dist/form/affiliations.d.ts +1 -292
- package/dist/form/affiliations.js +17 -2
- package/dist/form/apps.d.ts +1 -209
- package/dist/form/apps.js +17 -2
- package/dist/form/disciplines.d.ts +1 -40
- package/dist/form/disciplines.js +17 -2
- package/dist/form/events.d.ts +1 -1397
- package/dist/form/events.js +17 -2
- package/dist/form/fellowships.d.ts +1 -2122
- package/dist/form/fellowships.js +17 -2
- package/dist/form/files.d.ts +1 -40
- package/dist/form/files.js +17 -2
- package/dist/form/mailing.d.ts +1 -62
- package/dist/form/mailing.js +17 -2
- package/dist/form/news.d.ts +1 -405
- package/dist/form/news.js +17 -2
- package/dist/form/people.d.ts +1 -1062
- package/dist/form/people.js +17 -2
- package/dist/form/projects.d.ts +1 -564
- package/dist/form/projects.js +17 -2
- package/dist/form/publications.d.ts +1 -615
- package/dist/form/publications.js +17 -2
- package/dist/form/tags.d.ts +1 -54
- package/dist/form/tags.js +17 -2
- package/dist/form/users.d.ts +1 -946
- package/dist/form/users.js +17 -2
- package/dist/list/actions.d.ts +1 -103
- package/dist/list/actions.js +17 -2
- package/dist/list/affiliations.d.ts +1 -103
- package/dist/list/affiliations.js +17 -2
- package/dist/list/apps.d.ts +1 -103
- package/dist/list/apps.js +17 -2
- package/dist/list/disciplines.d.ts +1 -101
- package/dist/list/disciplines.js +17 -2
- package/dist/list/events.d.ts +1 -172
- package/dist/list/events.js +17 -2
- package/dist/list/fellowships.d.ts +1 -123
- package/dist/list/fellowships.js +17 -2
- package/dist/list/files.d.ts +1 -101
- package/dist/list/files.js +17 -2
- package/dist/list/mailing.d.ts +1 -101
- package/dist/list/mailing.js +17 -2
- package/dist/list/news.d.ts +1 -103
- package/dist/list/news.js +17 -2
- package/dist/list/people.d.ts +1 -153
- package/dist/list/people.js +17 -2
- package/dist/list/projects.d.ts +1 -103
- package/dist/list/projects.js +17 -2
- package/dist/list/publications.d.ts +1 -127
- package/dist/list/publications.js +17 -2
- package/dist/list/tags.d.ts +1 -103
- package/dist/list/tags.js +17 -2
- package/dist/list/users.d.ts +1 -153
- package/dist/list/users.js +17 -2
- package/package.json +1 -1
- package/readme.md +94 -17
package/dist/list/tags.js
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
// Deep freeze utility to make exports immutable
|
|
2
|
+
const deepFreeze = (obj) => {
|
|
3
|
+
Object.freeze(obj);
|
|
4
|
+
Object.getOwnPropertyNames(obj).forEach(prop => {
|
|
5
|
+
if (obj[prop] !== null
|
|
6
|
+
&& (typeof obj[prop] === "object" || typeof obj[prop] === "function")
|
|
7
|
+
&& !Object.isFrozen(obj[prop])) {
|
|
8
|
+
deepFreeze(obj[prop]);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
return obj;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const data = {
|
|
2
15
|
"items": [
|
|
3
16
|
{},
|
|
4
17
|
{},
|
|
@@ -130,4 +143,6 @@ export default {
|
|
|
130
143
|
"sortDesc": [
|
|
131
144
|
-1
|
|
132
145
|
]
|
|
133
|
-
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export default deepFreeze(data);
|
package/dist/list/users.d.ts
CHANGED
|
@@ -1,154 +1,2 @@
|
|
|
1
|
-
declare
|
|
2
|
-
let items: {}[];
|
|
3
|
-
let itemsPerPage: number;
|
|
4
|
-
let itemsPerPageArray: number[];
|
|
5
|
-
let filtersCount: number;
|
|
6
|
-
namespace views {
|
|
7
|
-
namespace rows {
|
|
8
|
-
let name: string;
|
|
9
|
-
let icon: string;
|
|
10
|
-
namespace perPage {
|
|
11
|
-
export let options: number[];
|
|
12
|
-
let _default: number;
|
|
13
|
-
export { _default as default };
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
namespace dense {
|
|
17
|
-
let _default_1: boolean;
|
|
18
|
-
export { _default_1 as default };
|
|
19
|
-
let name_1: string;
|
|
20
|
-
export { name_1 as name };
|
|
21
|
-
let icon_1: string;
|
|
22
|
-
export { icon_1 as icon };
|
|
23
|
-
export namespace perPage_1 {
|
|
24
|
-
let options_1: number[];
|
|
25
|
-
export { options_1 as options };
|
|
26
|
-
let _default_2: number;
|
|
27
|
-
export { _default_2 as default };
|
|
28
|
-
}
|
|
29
|
-
export { perPage_1 as perPage };
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
namespace sort {
|
|
33
|
-
namespace nameasc {
|
|
34
|
-
let icon_2: string;
|
|
35
|
-
export { icon_2 as icon };
|
|
36
|
-
export let text: string;
|
|
37
|
-
export let value: (string | number)[];
|
|
38
|
-
}
|
|
39
|
-
namespace namedesc {
|
|
40
|
-
let icon_3: string;
|
|
41
|
-
export { icon_3 as icon };
|
|
42
|
-
let text_1: string;
|
|
43
|
-
export { text_1 as text };
|
|
44
|
-
let value_1: (string | number)[];
|
|
45
|
-
export { value_1 as value };
|
|
46
|
-
}
|
|
47
|
-
namespace vintagedesc {
|
|
48
|
-
let icon_4: string;
|
|
49
|
-
export { icon_4 as icon };
|
|
50
|
-
let text_2: string;
|
|
51
|
-
export { text_2 as text };
|
|
52
|
-
let value_2: (string | number)[];
|
|
53
|
-
export { value_2 as value };
|
|
54
|
-
}
|
|
55
|
-
namespace vintageasc {
|
|
56
|
-
let icon_5: string;
|
|
57
|
-
export { icon_5 as icon };
|
|
58
|
-
let text_3: string;
|
|
59
|
-
export { text_3 as text };
|
|
60
|
-
let value_3: (string | number)[];
|
|
61
|
-
export { value_3 as value };
|
|
62
|
-
let _default_3: boolean;
|
|
63
|
-
export { _default_3 as default };
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
namespace view {
|
|
67
|
-
let _default_4: boolean;
|
|
68
|
-
export { _default_4 as default };
|
|
69
|
-
let name_2: string;
|
|
70
|
-
export { name_2 as name };
|
|
71
|
-
let icon_6: string;
|
|
72
|
-
export { icon_6 as icon };
|
|
73
|
-
export namespace perPage_2 {
|
|
74
|
-
let options_2: number[];
|
|
75
|
-
export { options_2 as options };
|
|
76
|
-
let _default_5: number;
|
|
77
|
-
export { _default_5 as default };
|
|
78
|
-
}
|
|
79
|
-
export { perPage_2 as perPage };
|
|
80
|
-
}
|
|
81
|
-
namespace filters {
|
|
82
|
-
namespace groups {
|
|
83
|
-
let type: string;
|
|
84
|
-
}
|
|
85
|
-
namespace vintage {
|
|
86
|
-
let type_1: string;
|
|
87
|
-
export { type_1 as type };
|
|
88
|
-
export namespace show {
|
|
89
|
-
let _default_6: boolean;
|
|
90
|
-
export { _default_6 as default };
|
|
91
|
-
export let switchIf: {
|
|
92
|
-
groups: string;
|
|
93
|
-
}[];
|
|
94
|
-
export let disjonctive: boolean;
|
|
95
|
-
}
|
|
96
|
-
export let multiple: boolean;
|
|
97
|
-
}
|
|
98
|
-
namespace programs {
|
|
99
|
-
let type_2: string;
|
|
100
|
-
export { type_2 as type };
|
|
101
|
-
export namespace show_1 {
|
|
102
|
-
let _default_7: boolean;
|
|
103
|
-
export { _default_7 as default };
|
|
104
|
-
let switchIf_1: {
|
|
105
|
-
groups: string;
|
|
106
|
-
}[];
|
|
107
|
-
export { switchIf_1 as switchIf };
|
|
108
|
-
let disjonctive_1: boolean;
|
|
109
|
-
export { disjonctive_1 as disjonctive };
|
|
110
|
-
}
|
|
111
|
-
export { show_1 as show };
|
|
112
|
-
let multiple_1: boolean;
|
|
113
|
-
export { multiple_1 as multiple };
|
|
114
|
-
}
|
|
115
|
-
namespace disciplines {
|
|
116
|
-
let type_3: string;
|
|
117
|
-
export { type_3 as type };
|
|
118
|
-
export namespace show_2 {
|
|
119
|
-
let _default_8: boolean;
|
|
120
|
-
export { _default_8 as default };
|
|
121
|
-
let switchIf_2: {
|
|
122
|
-
groups: string;
|
|
123
|
-
}[];
|
|
124
|
-
export { switchIf_2 as switchIf };
|
|
125
|
-
let disjonctive_2: boolean;
|
|
126
|
-
export { disjonctive_2 as disjonctive };
|
|
127
|
-
}
|
|
128
|
-
export { show_2 as show };
|
|
129
|
-
let multiple_2: boolean;
|
|
130
|
-
export { multiple_2 as multiple };
|
|
131
|
-
}
|
|
132
|
-
namespace member {
|
|
133
|
-
let type_4: string;
|
|
134
|
-
export { type_4 as type };
|
|
135
|
-
export namespace show_3 {
|
|
136
|
-
let _default_9: boolean;
|
|
137
|
-
export { _default_9 as default };
|
|
138
|
-
let switchIf_3: {
|
|
139
|
-
groups: string;
|
|
140
|
-
}[];
|
|
141
|
-
export { switchIf_3 as switchIf };
|
|
142
|
-
let disjonctive_3: boolean;
|
|
143
|
-
export { disjonctive_3 as disjonctive };
|
|
144
|
-
}
|
|
145
|
-
export { show_3 as show };
|
|
146
|
-
let multiple_3: boolean;
|
|
147
|
-
export { multiple_3 as multiple };
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
let limit: number;
|
|
151
|
-
let sortBy: string[];
|
|
152
|
-
let sortDesc: number[];
|
|
153
|
-
}
|
|
1
|
+
declare const _default: any;
|
|
154
2
|
export default _default;
|
package/dist/list/users.js
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
// Deep freeze utility to make exports immutable
|
|
2
|
+
const deepFreeze = (obj) => {
|
|
3
|
+
Object.freeze(obj);
|
|
4
|
+
Object.getOwnPropertyNames(obj).forEach(prop => {
|
|
5
|
+
if (obj[prop] !== null
|
|
6
|
+
&& (typeof obj[prop] === "object" || typeof obj[prop] === "function")
|
|
7
|
+
&& !Object.isFrozen(obj[prop])) {
|
|
8
|
+
deepFreeze(obj[prop]);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
return obj;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const data = {
|
|
2
15
|
"items": [
|
|
3
16
|
{},
|
|
4
17
|
{},
|
|
@@ -173,4 +186,6 @@ export default {
|
|
|
173
186
|
"sortDesc": [
|
|
174
187
|
1
|
|
175
188
|
]
|
|
176
|
-
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export default deepFreeze(data);
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# 🌳 @paris-ias/trees
|
|
4
4
|
|
|
5
|
-
**Isomorphic Forest
|
|
5
|
+
**Isomorphic Forest Trees Module**
|
|
6
6
|
|
|
7
7
|
_The foundational data model layer for the Paris IAS ecosystem_
|
|
8
8
|
|
|
@@ -28,18 +28,25 @@ graph LR
|
|
|
28
28
|
A --> E[Defaults Tree]
|
|
29
29
|
A --> F[GraphQL Operations]
|
|
30
30
|
|
|
31
|
-
B --> G[Type Safety]
|
|
31
|
+
B --> G[Type Safety & Immutability]
|
|
32
32
|
C --> H[Dynamic Forms]
|
|
33
33
|
D --> I[Smart Lists]
|
|
34
34
|
E --> J[Initialization]
|
|
35
35
|
F --> K[API Integration]
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
G --> L[TypeScript Declarations]
|
|
38
|
+
H --> L
|
|
39
|
+
I --> L
|
|
40
|
+
J --> L
|
|
41
|
+
K --> L
|
|
42
|
+
|
|
43
|
+
style A fill:#0277bd,color:#fff
|
|
44
|
+
style B fill:#6a1b9a,color:#fff
|
|
45
|
+
style C fill:#2e7d32,color:#fff
|
|
46
|
+
style D fill:#e65100,color:#fff
|
|
47
|
+
style E fill:#c2185b,color:#fff
|
|
48
|
+
style F fill:#1565c0,color:#fff
|
|
49
|
+
style L fill:#455a64,color:#fff
|
|
43
50
|
```
|
|
44
51
|
|
|
45
52
|
### Why Isomorphic Forests?
|
|
@@ -49,7 +56,8 @@ graph LR
|
|
|
49
56
|
- **🌍 I18n by Default**: Built-in internationalization support at the primitive level
|
|
50
57
|
- **🧩 Infinite Composition**: Template system enables unlimited reusable components
|
|
51
58
|
- **⚡ Type Safety**: Full TypeScript support with generated type definitions
|
|
52
|
-
-
|
|
59
|
+
- **� Immutable Exports**: All generated trees are deeply frozen and immutable
|
|
60
|
+
- **�📡 GraphQL Ready**: Automatically generates client operations and server schemas
|
|
53
61
|
|
|
54
62
|
---
|
|
55
63
|
|
|
@@ -69,7 +77,7 @@ Every data model is composed of five fundamental types that can be infinitely co
|
|
|
69
77
|
|
|
70
78
|
### 🌲 Generated Trees
|
|
71
79
|
|
|
72
|
-
Each model definition generates several distinct outputs
|
|
80
|
+
Each model definition generates several distinct outputs, all **immutable** and **fully typed**:
|
|
73
81
|
|
|
74
82
|
```typescript
|
|
75
83
|
// 1. Schema Tree - Type definitions and validation, first part used by forms
|
|
@@ -152,9 +160,12 @@ pnpm add @paris-ias/trees
|
|
|
152
160
|
### Importing Generated Trees
|
|
153
161
|
|
|
154
162
|
```typescript
|
|
155
|
-
// Import form and list configurations
|
|
163
|
+
// Import form and list configurations (immutable and fully typed)
|
|
156
164
|
import { formPeople, listPeople } from "@paris-ias/trees"
|
|
157
165
|
|
|
166
|
+
// All exports are deeply frozen - mutations will throw errors in strict mode
|
|
167
|
+
formPeople._defaults.firstname = "hack" // ❌ TypeError: Cannot assign to read only property
|
|
168
|
+
|
|
158
169
|
// Import GraphQL operations directly
|
|
159
170
|
import("@paris-ias/trees/dist/graphql/client/people/query.list.people.gql")
|
|
160
171
|
import("@paris-ias/trees/dist/graphql/client/events/query.get.events.gql")
|
|
@@ -274,12 +285,21 @@ graph TD
|
|
|
274
285
|
J --> O[Initialization]
|
|
275
286
|
K --> P[API Integration]
|
|
276
287
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
288
|
+
B --> Q[TypeScript Declarations]
|
|
289
|
+
C --> Q
|
|
290
|
+
D --> Q
|
|
291
|
+
E --> Q
|
|
292
|
+
F --> Q
|
|
293
|
+
Q --> R[Immutable Exports]
|
|
294
|
+
|
|
295
|
+
style A fill:#0277bd,color:#fff
|
|
296
|
+
style B fill:#6a1b9a,color:#fff
|
|
297
|
+
style C fill:#2e7d32,color:#fff
|
|
298
|
+
style D fill:#e65100,color:#fff
|
|
299
|
+
style E fill:#c2185b,color:#fff
|
|
300
|
+
style F fill:#1565c0,color:#fff
|
|
301
|
+
style Q fill:#455a64,color:#fff
|
|
302
|
+
style R fill:#d32f2f,color:#fff
|
|
283
303
|
```
|
|
284
304
|
|
|
285
305
|
### Directory (simplified) Structure
|
|
@@ -391,6 +411,63 @@ npm run clean && npm run generate
|
|
|
391
411
|
|
|
392
412
|
---
|
|
393
413
|
|
|
414
|
+
## 🔒 Immutability & Type Safety
|
|
415
|
+
|
|
416
|
+
### Deep Freeze Protection
|
|
417
|
+
|
|
418
|
+
All generated tree exports are **deeply frozen** using `Object.freeze()`, ensuring complete immutability:
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
import { formPeople } from "@paris-ias/trees"
|
|
422
|
+
|
|
423
|
+
// ❌ All mutations are prevented
|
|
424
|
+
formPeople._defaults.firstname = "hacked" // Fails silently (non-strict)
|
|
425
|
+
formPeople.schema.firstname.label = "modified" // TypeError in strict mode
|
|
426
|
+
formPeople.newProperty = "value" // Cannot extend frozen objects
|
|
427
|
+
delete formPeople._defaults // Cannot delete properties
|
|
428
|
+
|
|
429
|
+
// ✅ Safe to share across your application
|
|
430
|
+
const config1 = formPeople
|
|
431
|
+
const config2 = formPeople // Same reference, guaranteed unchanged
|
|
432
|
+
|
|
433
|
+
// ✅ Objects are frozen at all levels
|
|
434
|
+
Object.isFrozen(formPeople) // true
|
|
435
|
+
Object.isFrozen(formPeople._defaults) // true
|
|
436
|
+
Object.isFrozen(formPeople.schema) // true
|
|
437
|
+
Object.isFrozen(formPeople.schema.firstname) // true
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Full TypeScript Support
|
|
441
|
+
|
|
442
|
+
Complete type definitions are automatically generated for all exports:
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Imports include full type information
|
|
446
|
+
import { formPeople, listPeople, type Form, type List } from "@paris-ias/trees"
|
|
447
|
+
|
|
448
|
+
// IDE autocomplete and type checking work perfectly
|
|
449
|
+
const firstname = formPeople.schema.firstname // Fully typed
|
|
450
|
+
const defaultName = formPeople._defaults.firstname // Type: string | { en: string, fr: string }
|
|
451
|
+
|
|
452
|
+
// Type-safe development
|
|
453
|
+
function processForm(form: typeof formPeople) {
|
|
454
|
+
// Full intellisense and type checking
|
|
455
|
+
const schema = form.schema
|
|
456
|
+
const defaults = form._defaults
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Benefits
|
|
461
|
+
|
|
462
|
+
- **🛡️ Data Integrity**: Prevents accidental mutations throughout your codebase
|
|
463
|
+
- **🔄 Safe Sharing**: Share configuration objects without defensive copying
|
|
464
|
+
- **⚡ Performance**: Enables optimizations in React, Vue, and other frameworks
|
|
465
|
+
- **🐛 Easier Debugging**: Data structures never change unexpectedly
|
|
466
|
+
- **📝 Better Intellisense**: Full TypeScript support with autocomplete
|
|
467
|
+
- **✅ Type Safety**: Catch errors at compile time, not runtime
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
394
471
|
## 🌐 Internationalization
|
|
395
472
|
|
|
396
473
|
Every primitive field supports internationalization out of the box:
|