@objectstack/metadata 17.1.0 → 17.3.0
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/CHANGELOG.md +1541 -0
- package/dist/errors.cjs +1 -85
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +1 -22
- package/dist/errors.d.ts +1 -22
- package/dist/errors.js +2 -84
- package/dist/errors.js.map +1 -1
- package/dist/index.cjs +752 -272
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +360 -28
- package/dist/index.d.ts +360 -28
- package/dist/index.js +756 -270
- package/dist/index.js.map +1 -1
- package/dist/migrations/index.cjs +72 -46
- package/dist/migrations/index.cjs.map +1 -1
- package/dist/migrations/index.d.cts +57 -14
- package/dist/migrations/index.d.ts +57 -14
- package/dist/migrations/index.js +72 -46
- package/dist/migrations/index.js.map +1 -1
- package/dist/node.cjs +752 -272
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +133 -3
- package/dist/node.d.ts +133 -3
- package/dist/node.js +756 -270
- package/dist/node.js.map +1 -1
- package/package.json +42 -21
package/dist/node.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MetadataManager, MetadataManagerOptions, MetadataLoader, MetadataSerializer } from './index.cjs';
|
|
2
|
-
export { DatabaseLoader, DatabaseLoaderOptions, HistoryCleanupManager, JSONSerializer, MemoryLoader, MetadataPlugin, Migration, RemoteLoader, SerializeOptions, TypeScriptSerializer, WatchCallback, YAMLSerializer, calculateChecksum, generateDiffSummary, generateSimpleDiff } from './index.cjs';
|
|
1
|
+
import { MetadataManager, MetadataManagerOptions, MetadataLoader, MetadataSerializer, MetadataKeyedItem } from './index.cjs';
|
|
2
|
+
export { DatabaseLoader, DatabaseLoaderOptions, HistoryCleanupManager, JSONSerializer, MemoryLoader, MetadataPlugin, Migration, RemoteLoader, SerializeOptions, TypeScriptSerializer, WatchCallback, YAMLSerializer, calculateChecksum, deriveViewContainerObject, generateDiffSummary, generateSimpleDiff } from './index.cjs';
|
|
3
3
|
export { HistoryOptions, MetaRef, MetadataEvent, MetadataItem, MetadataItemHeader, MetadataRepository, SysMetadataHistoryObject, SysMetadataObject, WatchFilter } from '@objectstack/metadata-core';
|
|
4
4
|
import { MetadataLoaderContract, MetadataFormat, MetadataLoadOptions, MetadataLoadResult, MetadataStats, MetadataSaveOptions, MetadataSaveResult } from '@objectstack/spec/system';
|
|
5
5
|
export { MetadataCollectionInfo, MetadataDiffResult, MetadataFormat, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataSaveOptions, MetadataSaveResult, MetadataStats, MetadataWatchEvent } from '@objectstack/spec/system';
|
|
@@ -37,10 +37,140 @@ declare class FilesystemLoader implements MetadataLoader {
|
|
|
37
37
|
constructor(rootDir: string, serializers: Map<MetadataFormat, MetadataSerializer>, logger?: Logger | undefined);
|
|
38
38
|
load(type: string, name: string, options?: MetadataLoadOptions): Promise<MetadataLoadResult>;
|
|
39
39
|
loadMany<T = any>(type: string, options?: MetadataLoadOptions): Promise<T[]>;
|
|
40
|
+
/**
|
|
41
|
+
* [#14341] The keyed half of {@link loadMany} — see {@link MetadataKeyedItem}
|
|
42
|
+
* for why the store's key travels BESIDE the body instead of being folded
|
|
43
|
+
* into it.
|
|
44
|
+
*
|
|
45
|
+
* THE RULE, in one sentence: an item is keyed by this loader's own
|
|
46
|
+
* name-to-path derivation — {@link nameFromFilename}, the very basename
|
|
47
|
+
* derivation `list()` reports — ONLY where that derivation is a bijection for
|
|
48
|
+
* the file (it sits directly under `ROOT/TYPE/` and carries one of the
|
|
49
|
+
* extensions {@link findFile} tries, so `findFile(type, key)` resolves back to
|
|
50
|
+
* this same file); every other shape keeps the pre-#14205 behaviour verbatim,
|
|
51
|
+
* keyed by `body.name` when it has one and dropped when it has none.
|
|
52
|
+
*
|
|
53
|
+
* Why the rule stops there (PM ruling on #14341, 2026-09-02, knowingly over
|
|
54
|
+
* triage's "a nested path keeps whatever `list()` reports for it today"):
|
|
55
|
+
* `list()` and `findFile()` DISAGREE outside that shape. For
|
|
56
|
+
* `ROOT/TYPE/crm/account.json`, `list()` reports the bare `account`, but
|
|
57
|
+
* `findFile()` resolves that name against `ROOT/TYPE/account.json` and finds
|
|
58
|
+
* nothing — the only name reaching the file is `crm/account`, which nothing
|
|
59
|
+
* reports. An extension-less file is read by `loadMany()` and reported by
|
|
60
|
+
* `list()`, and `findFile()` resolves neither. Keying by either side would
|
|
61
|
+
* mint a name some other door cannot open, and two directories holding the
|
|
62
|
+
* same basename would collide in silence
|
|
63
|
+
* (`MetadataManager.admitLoaderItems()` keeps the first and says nothing).
|
|
64
|
+
* The card's own fence: "keying items under names nothing else uses … is
|
|
65
|
+
* worse than today's honest drop". So the drop stays exactly where the key is
|
|
66
|
+
* unsettled, and is pinned as a RECORD in
|
|
67
|
+
* `filesystem-loader-keyed-items.test.ts`.
|
|
68
|
+
*
|
|
69
|
+
* [#14486, partial] `list()` and {@link findFile} have since converged on
|
|
70
|
+
* {@link resolvableNameForPath} — the derivation this method already used —
|
|
71
|
+
* so a nested or extension-less file is now neither listed nor resolvable.
|
|
72
|
+
* What did NOT change is the WALK behind this method: `loadManyEntries()`
|
|
73
|
+
* still READS those files, so `loadMany()` still returns their bodies and
|
|
74
|
+
* this method still falls back to `body.name` for them. That half of the
|
|
75
|
+
* #14486 ruling ("nothing unlisted is returned by `loadMany()` either") is
|
|
76
|
+
* deliberately NOT taken here: it would invert the three landed #14341 pins
|
|
77
|
+
* in `filesystem-loader-keyed-items.test.ts:113,167,187` and the
|
|
78
|
+
* `loadMany()` CONTROL at `:196`, and that file was under a concurrent
|
|
79
|
+
* claim (PR #14627) when this landed. The remaining divergence — listed ⊂
|
|
80
|
+
* loaded — is pinned as a RECORD in
|
|
81
|
+
* `filesystem-loader-list-reachability.test.ts` rather than left implicit.
|
|
82
|
+
*
|
|
83
|
+
* One consequence, deliberate: a flat file whose `body.name` DISAGREES with
|
|
84
|
+
* its basename is now keyed by the BASENAME. That is #14205's rule (identity
|
|
85
|
+
* is the key the store holds an item under, not `body.name`) applied to this
|
|
86
|
+
* loader, and it aligns `MetadataManager.list()` with `listNames()` for that
|
|
87
|
+
* shape.
|
|
88
|
+
*
|
|
89
|
+
* The body is handed back by reference, unchanged: nothing is written into a
|
|
90
|
+
* body that deliberately has no `name`. `limit` bounds the items LOADED,
|
|
91
|
+
* exactly as `loadMany()` does — an entry the key rule drops has still been
|
|
92
|
+
* read and still counts against it.
|
|
93
|
+
*/
|
|
94
|
+
loadManyKeyed<T = any>(type: string, options?: MetadataLoadOptions): Promise<MetadataKeyedItem<T>[]>;
|
|
95
|
+
/**
|
|
96
|
+
* The single walk behind {@link loadMany} and {@link loadManyKeyed}: one glob,
|
|
97
|
+
* one serializer pass, one `limit`. Shared so the two can never answer with
|
|
98
|
+
* different bodies for the same file — {@link MetadataLoader.loadManyKeyed}
|
|
99
|
+
* requires `data` to be "the same body `loadMany()` would return for the
|
|
100
|
+
* item", and a second copy of this walk is how that would quietly stop being
|
|
101
|
+
* true.
|
|
102
|
+
*/
|
|
103
|
+
private loadManyEntries;
|
|
40
104
|
exists(type: string, name: string): Promise<boolean>;
|
|
41
105
|
stat(type: string, name: string): Promise<MetadataStats | null>;
|
|
106
|
+
/**
|
|
107
|
+
* [#14486] The names this loader can be asked for, and ONLY those: a file
|
|
108
|
+
* directly under `ROOT/TYPE/` carrying an extension one of this instance's
|
|
109
|
+
* REGISTERED serializers claims. Every name it reports resolves back through
|
|
110
|
+
* {@link findFile}, so `listNames()` and `get()` give the same answer.
|
|
111
|
+
*
|
|
112
|
+
* It used to report `path.basename(file, ext)` for every file the glob found,
|
|
113
|
+
* nested or not, extension or not — and {@link findFile} resolves neither
|
|
114
|
+
* shape. `ROOT/TYPE/crm/account.json` was listed as `account`, which resolves
|
|
115
|
+
* against `ROOT/TYPE/account.json` and finds nothing; an extension-less
|
|
116
|
+
* `ROOT/TYPE/noext` was listed as `noext`, which resolves under no appended
|
|
117
|
+
* extension at all. A name in the list that `get()` answers `null` for is the
|
|
118
|
+
* silent failure an author (human or AI) reads as their own typo, so they
|
|
119
|
+
* retry the same word: the list and the door now agree instead.
|
|
120
|
+
*
|
|
121
|
+
* Ruling (maintainer, via the director seat on #14486, 2026-09-02): narrow
|
|
122
|
+
* the list — direction A, over B (reverse-unify: report `crm/account` and
|
|
123
|
+
* teach `findFile()` path-shaped names), which would have made a slash inside
|
|
124
|
+
* a metadata name every consumer's permanent obligation with no measured
|
|
125
|
+
* demand for it. The two-segment layout follows ADR-0008 §10, which
|
|
126
|
+
* `metadata-fs`'s `parseItemPath()` already enforces for its own store; the
|
|
127
|
+
* EXTENSION set deliberately does NOT follow §10's `.json`-only rule — see
|
|
128
|
+
* {@link resolvableExtensions} for why.
|
|
129
|
+
*/
|
|
42
130
|
list(type: string): Promise<string[]>;
|
|
43
131
|
save(type: string, name: string, data: any, options?: MetadataSaveOptions): Promise<MetadataSaveResult>;
|
|
132
|
+
/**
|
|
133
|
+
* The inverse of {@link detectFormat}: which file extensions carry which
|
|
134
|
+
* format. Fixed ORDER, because it is also {@link findFile}'s precedence when
|
|
135
|
+
* two files under one type directory share a stem — registration order must
|
|
136
|
+
* not be able to change which file `ROOT/TYPE/NAME` opens.
|
|
137
|
+
*/
|
|
138
|
+
private static readonly EXTENSIONS_BY_FORMAT;
|
|
139
|
+
/**
|
|
140
|
+
* [#14486] The extensions a name can be resolved under, for THIS instance:
|
|
141
|
+
* the ones belonging to the serializer set it was constructed with. Shared by
|
|
142
|
+
* {@link findFile}, {@link resolvableNameForPath} and therefore {@link list},
|
|
143
|
+
* so the set a name can be RESOLVED under cannot drift from the set that is
|
|
144
|
+
* LISTED or the set {@link loadManyKeyed} is willing to KEY by.
|
|
145
|
+
*
|
|
146
|
+
* Registered, not hard-coded, and deliberately not ADR-0008 §10's `.json`
|
|
147
|
+
* only. §10 governs the `metadata-fs` store; applying it verbatim here would
|
|
148
|
+
* drop `.yaml` and `.ts` metadata out of `listNames()` — a breakage this card
|
|
149
|
+
* never asked for. Under the manager's DEFAULT format set
|
|
150
|
+
* (`typescript` / `json` / `yaml`, `metadata-manager.ts`) that leaves `.js`
|
|
151
|
+
* out, which is the card's row-4 membership mismatch closing for free: a `.js`
|
|
152
|
+
* file was listed and resolvable while `loadMany()` could never return it and
|
|
153
|
+
* `load()` threw `No serializer found for format: javascript`. Register
|
|
154
|
+
* `javascript` and it is listed, resolvable and loadable together.
|
|
155
|
+
*/
|
|
156
|
+
private resolvableExtensions;
|
|
157
|
+
/**
|
|
158
|
+
* The metadata name this loader reports for a file: the basename with its
|
|
159
|
+
* extension stripped. One derivation, shared by {@link list} and
|
|
160
|
+
* {@link loadManyKeyed}, so the two cannot drift for the shape where they
|
|
161
|
+
* agree — `dotted.config.json` is `dotted.config` for both.
|
|
162
|
+
*/
|
|
163
|
+
private static nameFromFilename;
|
|
164
|
+
/**
|
|
165
|
+
* The key for a file IF this loader's name-to-path mapping is a bijection for
|
|
166
|
+
* it: a file directly under `ROOT/TYPE/` carrying an extension
|
|
167
|
+
* {@link findFile} tries, so `findFile(type, key)` resolves back to this very
|
|
168
|
+
* file. `null` for every other shape — a nested path, an extension-less file,
|
|
169
|
+
* an extension spelled in a case `findFile()` does not compose — which is why
|
|
170
|
+
* {@link loadManyKeyed} falls back to `body.name` there rather than minting a
|
|
171
|
+
* key no other door can open.
|
|
172
|
+
*/
|
|
173
|
+
private resolvableNameForPath;
|
|
44
174
|
/**
|
|
45
175
|
* Find file for a given type and name
|
|
46
176
|
*/
|
|
@@ -61,4 +191,4 @@ declare class FilesystemLoader implements MetadataLoader {
|
|
|
61
191
|
private generateETag;
|
|
62
192
|
}
|
|
63
193
|
|
|
64
|
-
export { FilesystemLoader, MetadataLoader, MetadataManager, MetadataManagerOptions, MetadataSerializer, NodeMetadataManager };
|
|
194
|
+
export { FilesystemLoader, MetadataKeyedItem, MetadataLoader, MetadataManager, MetadataManagerOptions, MetadataSerializer, NodeMetadataManager };
|
package/dist/node.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MetadataManager, MetadataManagerOptions, MetadataLoader, MetadataSerializer } from './index.js';
|
|
2
|
-
export { DatabaseLoader, DatabaseLoaderOptions, HistoryCleanupManager, JSONSerializer, MemoryLoader, MetadataPlugin, Migration, RemoteLoader, SerializeOptions, TypeScriptSerializer, WatchCallback, YAMLSerializer, calculateChecksum, generateDiffSummary, generateSimpleDiff } from './index.js';
|
|
1
|
+
import { MetadataManager, MetadataManagerOptions, MetadataLoader, MetadataSerializer, MetadataKeyedItem } from './index.js';
|
|
2
|
+
export { DatabaseLoader, DatabaseLoaderOptions, HistoryCleanupManager, JSONSerializer, MemoryLoader, MetadataPlugin, Migration, RemoteLoader, SerializeOptions, TypeScriptSerializer, WatchCallback, YAMLSerializer, calculateChecksum, deriveViewContainerObject, generateDiffSummary, generateSimpleDiff } from './index.js';
|
|
3
3
|
export { HistoryOptions, MetaRef, MetadataEvent, MetadataItem, MetadataItemHeader, MetadataRepository, SysMetadataHistoryObject, SysMetadataObject, WatchFilter } from '@objectstack/metadata-core';
|
|
4
4
|
import { MetadataLoaderContract, MetadataFormat, MetadataLoadOptions, MetadataLoadResult, MetadataStats, MetadataSaveOptions, MetadataSaveResult } from '@objectstack/spec/system';
|
|
5
5
|
export { MetadataCollectionInfo, MetadataDiffResult, MetadataFormat, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataManagerConfig, MetadataSaveOptions, MetadataSaveResult, MetadataStats, MetadataWatchEvent } from '@objectstack/spec/system';
|
|
@@ -37,10 +37,140 @@ declare class FilesystemLoader implements MetadataLoader {
|
|
|
37
37
|
constructor(rootDir: string, serializers: Map<MetadataFormat, MetadataSerializer>, logger?: Logger | undefined);
|
|
38
38
|
load(type: string, name: string, options?: MetadataLoadOptions): Promise<MetadataLoadResult>;
|
|
39
39
|
loadMany<T = any>(type: string, options?: MetadataLoadOptions): Promise<T[]>;
|
|
40
|
+
/**
|
|
41
|
+
* [#14341] The keyed half of {@link loadMany} — see {@link MetadataKeyedItem}
|
|
42
|
+
* for why the store's key travels BESIDE the body instead of being folded
|
|
43
|
+
* into it.
|
|
44
|
+
*
|
|
45
|
+
* THE RULE, in one sentence: an item is keyed by this loader's own
|
|
46
|
+
* name-to-path derivation — {@link nameFromFilename}, the very basename
|
|
47
|
+
* derivation `list()` reports — ONLY where that derivation is a bijection for
|
|
48
|
+
* the file (it sits directly under `ROOT/TYPE/` and carries one of the
|
|
49
|
+
* extensions {@link findFile} tries, so `findFile(type, key)` resolves back to
|
|
50
|
+
* this same file); every other shape keeps the pre-#14205 behaviour verbatim,
|
|
51
|
+
* keyed by `body.name` when it has one and dropped when it has none.
|
|
52
|
+
*
|
|
53
|
+
* Why the rule stops there (PM ruling on #14341, 2026-09-02, knowingly over
|
|
54
|
+
* triage's "a nested path keeps whatever `list()` reports for it today"):
|
|
55
|
+
* `list()` and `findFile()` DISAGREE outside that shape. For
|
|
56
|
+
* `ROOT/TYPE/crm/account.json`, `list()` reports the bare `account`, but
|
|
57
|
+
* `findFile()` resolves that name against `ROOT/TYPE/account.json` and finds
|
|
58
|
+
* nothing — the only name reaching the file is `crm/account`, which nothing
|
|
59
|
+
* reports. An extension-less file is read by `loadMany()` and reported by
|
|
60
|
+
* `list()`, and `findFile()` resolves neither. Keying by either side would
|
|
61
|
+
* mint a name some other door cannot open, and two directories holding the
|
|
62
|
+
* same basename would collide in silence
|
|
63
|
+
* (`MetadataManager.admitLoaderItems()` keeps the first and says nothing).
|
|
64
|
+
* The card's own fence: "keying items under names nothing else uses … is
|
|
65
|
+
* worse than today's honest drop". So the drop stays exactly where the key is
|
|
66
|
+
* unsettled, and is pinned as a RECORD in
|
|
67
|
+
* `filesystem-loader-keyed-items.test.ts`.
|
|
68
|
+
*
|
|
69
|
+
* [#14486, partial] `list()` and {@link findFile} have since converged on
|
|
70
|
+
* {@link resolvableNameForPath} — the derivation this method already used —
|
|
71
|
+
* so a nested or extension-less file is now neither listed nor resolvable.
|
|
72
|
+
* What did NOT change is the WALK behind this method: `loadManyEntries()`
|
|
73
|
+
* still READS those files, so `loadMany()` still returns their bodies and
|
|
74
|
+
* this method still falls back to `body.name` for them. That half of the
|
|
75
|
+
* #14486 ruling ("nothing unlisted is returned by `loadMany()` either") is
|
|
76
|
+
* deliberately NOT taken here: it would invert the three landed #14341 pins
|
|
77
|
+
* in `filesystem-loader-keyed-items.test.ts:113,167,187` and the
|
|
78
|
+
* `loadMany()` CONTROL at `:196`, and that file was under a concurrent
|
|
79
|
+
* claim (PR #14627) when this landed. The remaining divergence — listed ⊂
|
|
80
|
+
* loaded — is pinned as a RECORD in
|
|
81
|
+
* `filesystem-loader-list-reachability.test.ts` rather than left implicit.
|
|
82
|
+
*
|
|
83
|
+
* One consequence, deliberate: a flat file whose `body.name` DISAGREES with
|
|
84
|
+
* its basename is now keyed by the BASENAME. That is #14205's rule (identity
|
|
85
|
+
* is the key the store holds an item under, not `body.name`) applied to this
|
|
86
|
+
* loader, and it aligns `MetadataManager.list()` with `listNames()` for that
|
|
87
|
+
* shape.
|
|
88
|
+
*
|
|
89
|
+
* The body is handed back by reference, unchanged: nothing is written into a
|
|
90
|
+
* body that deliberately has no `name`. `limit` bounds the items LOADED,
|
|
91
|
+
* exactly as `loadMany()` does — an entry the key rule drops has still been
|
|
92
|
+
* read and still counts against it.
|
|
93
|
+
*/
|
|
94
|
+
loadManyKeyed<T = any>(type: string, options?: MetadataLoadOptions): Promise<MetadataKeyedItem<T>[]>;
|
|
95
|
+
/**
|
|
96
|
+
* The single walk behind {@link loadMany} and {@link loadManyKeyed}: one glob,
|
|
97
|
+
* one serializer pass, one `limit`. Shared so the two can never answer with
|
|
98
|
+
* different bodies for the same file — {@link MetadataLoader.loadManyKeyed}
|
|
99
|
+
* requires `data` to be "the same body `loadMany()` would return for the
|
|
100
|
+
* item", and a second copy of this walk is how that would quietly stop being
|
|
101
|
+
* true.
|
|
102
|
+
*/
|
|
103
|
+
private loadManyEntries;
|
|
40
104
|
exists(type: string, name: string): Promise<boolean>;
|
|
41
105
|
stat(type: string, name: string): Promise<MetadataStats | null>;
|
|
106
|
+
/**
|
|
107
|
+
* [#14486] The names this loader can be asked for, and ONLY those: a file
|
|
108
|
+
* directly under `ROOT/TYPE/` carrying an extension one of this instance's
|
|
109
|
+
* REGISTERED serializers claims. Every name it reports resolves back through
|
|
110
|
+
* {@link findFile}, so `listNames()` and `get()` give the same answer.
|
|
111
|
+
*
|
|
112
|
+
* It used to report `path.basename(file, ext)` for every file the glob found,
|
|
113
|
+
* nested or not, extension or not — and {@link findFile} resolves neither
|
|
114
|
+
* shape. `ROOT/TYPE/crm/account.json` was listed as `account`, which resolves
|
|
115
|
+
* against `ROOT/TYPE/account.json` and finds nothing; an extension-less
|
|
116
|
+
* `ROOT/TYPE/noext` was listed as `noext`, which resolves under no appended
|
|
117
|
+
* extension at all. A name in the list that `get()` answers `null` for is the
|
|
118
|
+
* silent failure an author (human or AI) reads as their own typo, so they
|
|
119
|
+
* retry the same word: the list and the door now agree instead.
|
|
120
|
+
*
|
|
121
|
+
* Ruling (maintainer, via the director seat on #14486, 2026-09-02): narrow
|
|
122
|
+
* the list — direction A, over B (reverse-unify: report `crm/account` and
|
|
123
|
+
* teach `findFile()` path-shaped names), which would have made a slash inside
|
|
124
|
+
* a metadata name every consumer's permanent obligation with no measured
|
|
125
|
+
* demand for it. The two-segment layout follows ADR-0008 §10, which
|
|
126
|
+
* `metadata-fs`'s `parseItemPath()` already enforces for its own store; the
|
|
127
|
+
* EXTENSION set deliberately does NOT follow §10's `.json`-only rule — see
|
|
128
|
+
* {@link resolvableExtensions} for why.
|
|
129
|
+
*/
|
|
42
130
|
list(type: string): Promise<string[]>;
|
|
43
131
|
save(type: string, name: string, data: any, options?: MetadataSaveOptions): Promise<MetadataSaveResult>;
|
|
132
|
+
/**
|
|
133
|
+
* The inverse of {@link detectFormat}: which file extensions carry which
|
|
134
|
+
* format. Fixed ORDER, because it is also {@link findFile}'s precedence when
|
|
135
|
+
* two files under one type directory share a stem — registration order must
|
|
136
|
+
* not be able to change which file `ROOT/TYPE/NAME` opens.
|
|
137
|
+
*/
|
|
138
|
+
private static readonly EXTENSIONS_BY_FORMAT;
|
|
139
|
+
/**
|
|
140
|
+
* [#14486] The extensions a name can be resolved under, for THIS instance:
|
|
141
|
+
* the ones belonging to the serializer set it was constructed with. Shared by
|
|
142
|
+
* {@link findFile}, {@link resolvableNameForPath} and therefore {@link list},
|
|
143
|
+
* so the set a name can be RESOLVED under cannot drift from the set that is
|
|
144
|
+
* LISTED or the set {@link loadManyKeyed} is willing to KEY by.
|
|
145
|
+
*
|
|
146
|
+
* Registered, not hard-coded, and deliberately not ADR-0008 §10's `.json`
|
|
147
|
+
* only. §10 governs the `metadata-fs` store; applying it verbatim here would
|
|
148
|
+
* drop `.yaml` and `.ts` metadata out of `listNames()` — a breakage this card
|
|
149
|
+
* never asked for. Under the manager's DEFAULT format set
|
|
150
|
+
* (`typescript` / `json` / `yaml`, `metadata-manager.ts`) that leaves `.js`
|
|
151
|
+
* out, which is the card's row-4 membership mismatch closing for free: a `.js`
|
|
152
|
+
* file was listed and resolvable while `loadMany()` could never return it and
|
|
153
|
+
* `load()` threw `No serializer found for format: javascript`. Register
|
|
154
|
+
* `javascript` and it is listed, resolvable and loadable together.
|
|
155
|
+
*/
|
|
156
|
+
private resolvableExtensions;
|
|
157
|
+
/**
|
|
158
|
+
* The metadata name this loader reports for a file: the basename with its
|
|
159
|
+
* extension stripped. One derivation, shared by {@link list} and
|
|
160
|
+
* {@link loadManyKeyed}, so the two cannot drift for the shape where they
|
|
161
|
+
* agree — `dotted.config.json` is `dotted.config` for both.
|
|
162
|
+
*/
|
|
163
|
+
private static nameFromFilename;
|
|
164
|
+
/**
|
|
165
|
+
* The key for a file IF this loader's name-to-path mapping is a bijection for
|
|
166
|
+
* it: a file directly under `ROOT/TYPE/` carrying an extension
|
|
167
|
+
* {@link findFile} tries, so `findFile(type, key)` resolves back to this very
|
|
168
|
+
* file. `null` for every other shape — a nested path, an extension-less file,
|
|
169
|
+
* an extension spelled in a case `findFile()` does not compose — which is why
|
|
170
|
+
* {@link loadManyKeyed} falls back to `body.name` there rather than minting a
|
|
171
|
+
* key no other door can open.
|
|
172
|
+
*/
|
|
173
|
+
private resolvableNameForPath;
|
|
44
174
|
/**
|
|
45
175
|
* Find file for a given type and name
|
|
46
176
|
*/
|
|
@@ -61,4 +191,4 @@ declare class FilesystemLoader implements MetadataLoader {
|
|
|
61
191
|
private generateETag;
|
|
62
192
|
}
|
|
63
193
|
|
|
64
|
-
export { FilesystemLoader, MetadataLoader, MetadataManager, MetadataManagerOptions, MetadataSerializer, NodeMetadataManager };
|
|
194
|
+
export { FilesystemLoader, MetadataKeyedItem, MetadataLoader, MetadataManager, MetadataManagerOptions, MetadataSerializer, NodeMetadataManager };
|