@obsidiane/meridiane 1.0.1 → 2.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.
@@ -13,10 +13,11 @@ export function isObject(v) {
13
13
  /**
14
14
  * Extrait le nom du schéma depuis une référence $ref
15
15
  * @param {string} $ref
16
+ * @returns {string|undefined}
16
17
  */
17
18
  export function schemaNameFromRef($ref) {
18
19
  const m = $ref.match(/#\/components\/schemas\/(.+)$/);
19
- return m ? m[1] : $ref;
20
+ return m ? m[1] : undefined;
20
21
  }
21
22
 
22
23
  /**
@@ -31,7 +32,7 @@ export function mergeAllOf(schemas) {
31
32
  for (const s of schemas) {
32
33
  if (s.$ref) {
33
34
  const ref = schemaNameFromRef(s.$ref);
34
- if (HYDRA_BASE_RE.test(ref)) {
35
+ if (ref && HYDRA_BASE_RE.test(ref)) {
35
36
  continue;
36
37
  }
37
38
  return null;
@@ -46,101 +47,3 @@ export function mergeAllOf(schemas) {
46
47
  out.required = [...new Set(out.required)];
47
48
  return out;
48
49
  }
49
-
50
- /**
51
- * Liste les noms de schémas dans `components.schemas`.
52
- * La sélection/filtres est gérée par `applySchemaNameFilters`.
53
- * @param {Record<string, any>} schemas
54
- * @returns {string[]}
55
- */
56
- export function filterSchemaNames(schemas, cfg) {
57
- return Object.keys(schemas).sort((a, b) => a.localeCompare(b));
58
- }
59
-
60
- /**
61
- * @param {unknown} rule
62
- * @returns {rule is ((name: string) => boolean)}
63
- */
64
- function isRuleFn(rule) {
65
- return typeof rule === 'function';
66
- }
67
-
68
- /**
69
- * @param {string} name
70
- * @param {RegExp|string|((name: string) => boolean)} rule
71
- */
72
- function matchesRule(name, rule) {
73
- if (rule instanceof RegExp) return rule.test(name);
74
- if (isRuleFn(rule)) return !!rule(name);
75
- if (typeof rule === 'string' && rule.length) return name.includes(rule);
76
- return false;
77
- }
78
-
79
- /**
80
- * Applique un preset de génération et/ou des règles include/exclude.
81
- *
82
- * - `preset: "all"`: ne filtre rien (comportement par défaut)
83
- * - `preset: "native"`: retire les schémas "techniques" (Hydra*, jsonMergePatch…)
84
- *
85
- * Les règles `includeSchemaNames` / `excludeSchemaNames` s'appliquent sur les noms
86
- * de schémas OpenAPI (ex: "User-user.read", "Conversation.jsonMergePatch", …).
87
- *
88
- * @param {string[]} schemaNames
89
- * @param {{
90
- * preset?: 'all'|'native',
91
- * includeSchemaNames?: Array<RegExp|string|((name: string) => boolean)>,
92
- * excludeSchemaNames?: Array<RegExp|string|((name: string) => boolean)>,
93
- * }} [cfg]
94
- */
95
- export function applySchemaNameFilters(schemaNames, cfg) {
96
- const preset = cfg?.preset ?? 'all';
97
-
98
- /** @type {Array<RegExp|string|((name: string) => boolean)>} */
99
- const include = Array.isArray(cfg?.includeSchemaNames) ? cfg.includeSchemaNames : [];
100
- /** @type {Array<RegExp|string|((name: string) => boolean)>} */
101
- const exclude = Array.isArray(cfg?.excludeSchemaNames) ? [...cfg.excludeSchemaNames] : [];
102
-
103
- // 1) include/exclude user filters (always applied first)
104
- const hasInclude = include.length > 0;
105
- let out = schemaNames.filter((name) => {
106
- if (hasInclude && !include.some((r) => matchesRule(name, r))) return false;
107
- if (exclude.some((r) => matchesRule(name, r))) return false;
108
- return true;
109
- });
110
-
111
- // 2) preset filters
112
- if (preset === 'native') {
113
- out = out
114
- .filter((n) => !/^Hydra/i.test(n))
115
- // API Platform adds a technical "Multipart" schema for multipart/form-data request bodies (file uploads).
116
- // It's not a resource model and tends to pollute the generated "native" model list.
117
- .filter((n) => !/^Multipart(?:$|[.-])/i.test(n))
118
- .filter((n) => !/jsonMergePatch/i.test(n))
119
- .filter((n) => !/\.jsonld\b/i.test(n))
120
- .filter((n) => !/\.jsonapi\b/i.test(n));
121
-
122
- // 3) collapse group variants: keep one schema per base (before `-`)
123
- const score = (name) => {
124
- if (!name.includes('-')) return 100;
125
- const group = name.split('-').slice(1).join('-');
126
- if (/(^|[.\-])read($|[.\-])/i.test(group)) return 50;
127
- return 0;
128
- };
129
- const byBase = new Map();
130
- for (const name of out) {
131
- const base = name.split('-')[0];
132
- const prev = byBase.get(base);
133
- if (!prev) {
134
- byBase.set(base, name);
135
- continue;
136
- }
137
- const a = prev, b = name;
138
- const sa = score(a), sb = score(b);
139
- if (sb > sa) byBase.set(base, b);
140
- else if (sb === sa && b.localeCompare(a) < 0) byBase.set(base, b);
141
- }
142
- out = [...byBase.values()].sort((a, b) => a.localeCompare(b));
143
- }
144
-
145
- return out;
146
- }
@@ -1,9 +1,11 @@
1
+ {{#if extendsItem}}
1
2
  import type { Item } from '../lib/ports/resource-repository.port';
3
+ {{/if}}
2
4
  {{#each imports}}
3
5
  import type { {{this}} } from './{{this}}';
4
6
  {{/each}}
5
7
 
6
- export interface {{name}} extends Item{{#each extendsTypes}}, {{this}}{{/each}} {
8
+ export interface {{name}}{{#if extendsItem}} extends Item{{#each extendsTypes}}, {{this}}{{/each}}{{else}}{{#each extendsTypes}}{{#if @first}} extends {{this}}{{else}}, {{this}}{{/if}}{{/each}}{{/if}} {
7
9
  {{#each props}}
8
10
  {{{tsKey}}}{{#if optional}}?{{/if}}: {{type}};
9
11
  {{/each}}
@@ -16,16 +16,19 @@ export function withNullable(ts, schema) {
16
16
  * @param {any} schema
17
17
  * @param {Set<string>} deps
18
18
  * @param {Map<string,string>} nameMap
19
- * @param {{ requiredMode?: 'all-optional'|'spec', forceNullable?: boolean }} [cfg]
19
+ * @param {{ requiredMode?: 'all'|'spec' }} [cfg]
20
20
  * @returns {string}
21
21
  */
22
22
  export function tsTypeOf(schema, deps, nameMap, cfg) {
23
23
  if (!schema) return 'any';
24
- const requiredMode = cfg?.requiredMode ?? 'all-optional';
25
- const forceNullable = !!cfg?.forceNullable;
24
+ const requiredMode = cfg?.requiredMode ?? 'all';
25
+ const forceNullable = requiredMode !== 'spec';
26
26
 
27
27
  if (schema.$ref) {
28
28
  const orig = schemaNameFromRef(schema.$ref);
29
+ if (!orig) return 'any';
30
+ if (/jsonMergePatch/i.test(orig)) return 'any';
31
+ if (/^Hydra/i.test(orig)) return 'any';
29
32
  const name = nameMap.get(orig) || orig;
30
33
  deps.add(name);
31
34
  return name;
@@ -1,26 +0,0 @@
1
- /**
2
- * Construit un label "tokenisé" (sans `.` ni `-`) à partir d'un nom de schéma OpenAPI.
3
- * Le label est ensuite passé à `sanitizeTypeName()` pour produire un identifiant TS stable.
4
- *
5
- * @param {string} original
6
- * @param {{ preset: 'all'|'native' }} cfg
7
- */
8
- export function schemaLabel(original, cfg) {
9
- const preset = cfg?.preset ?? 'all';
10
- if (preset === 'native') {
11
- // En native, on vise un nom "entity-like" : on ignore le groupe (après `-`) si présent.
12
- // Les variantes .jsonld/.jsonapi/jsonMergePatch sont censées être filtrées par le preset.
13
- return String(original).split('-')[0];
14
- }
15
-
16
- // En all, on encode tout : `.` et `-` deviennent des séparateurs de tokens.
17
- const rawTokens = String(original).split(/[.-]/g).filter(Boolean);
18
- const tokens = rawTokens.map((t) => {
19
- const lower = t.toLowerCase();
20
- if (lower === 'jsonld') return 'Jsonld';
21
- if (lower === 'jsonapi') return 'Jsonapi';
22
- if (lower === 'jsonmergepatch' || t === 'jsonMergePatch') return 'JsonMergePatch';
23
- return t;
24
- });
25
- return tokens.join(' ');
26
- }