@metaobjectsdev/sdk 0.7.0-rc.1 → 0.7.0-rc.3
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/memory.js +16 -9
- package/dist/memory.js.map +1 -1
- package/package.json +2 -2
- package/src/forge-types.ts +38 -20
- package/src/index.ts +9 -2
- package/src/memory.ts +73 -17
package/dist/memory.js
CHANGED
|
@@ -60,21 +60,25 @@ async function collectMetadataPaths(repoRoot) {
|
|
|
60
60
|
for (const pkg of ordered) {
|
|
61
61
|
// Each workspace package's metadata lives alongside its .meta/ dir
|
|
62
62
|
const pkgRoot = join(pkg.metaDir, "..");
|
|
63
|
-
paths.push(...(await
|
|
63
|
+
paths.push(...(await listMetadataFiles(join(pkgRoot, DEFAULT_METADATA_DIR))));
|
|
64
64
|
}
|
|
65
65
|
return paths;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
// Single-package path: scan metaobjects/ at the project root
|
|
69
|
-
return
|
|
69
|
+
return listMetadataFiles(join(repoRoot, DEFAULT_METADATA_DIR));
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
|
-
* Recursively list *.json
|
|
73
|
-
* any level. Subdirectories (e.g. projections/) are
|
|
74
|
-
* Files within a directory are sorted alphabetically for
|
|
75
|
-
* order; subdirectories are visited after files at the
|
|
72
|
+
* Recursively list metadata files (*.json, *.yaml, *.yml) under a directory,
|
|
73
|
+
* excluding _pending/ at any level. Subdirectories (e.g. projections/) are
|
|
74
|
+
* walked depth-first. Files within a directory are sorted alphabetically for
|
|
75
|
+
* deterministic load order; subdirectories are visited after files at the
|
|
76
|
+
* same level.
|
|
77
|
+
*
|
|
78
|
+
* Format selection (parsing) happens downstream in `FileSource` from
|
|
79
|
+
* `@metaobjectsdev/metadata`, which infers the parser from file extension.
|
|
76
80
|
*/
|
|
77
|
-
async function
|
|
81
|
+
async function listMetadataFiles(dir) {
|
|
78
82
|
let entries;
|
|
79
83
|
try {
|
|
80
84
|
entries = await readdir(dir);
|
|
@@ -92,14 +96,17 @@ async function listJsonFiles(dir) {
|
|
|
92
96
|
if (s.isDirectory()) {
|
|
93
97
|
subdirs.push(full);
|
|
94
98
|
}
|
|
95
|
-
else if (s.isFile() && entry
|
|
99
|
+
else if (s.isFile() && isMetadataFile(entry)) {
|
|
96
100
|
paths.push(full);
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
103
|
// Recurse into subdirectories after collecting files at this level
|
|
100
104
|
for (const sub of subdirs.sort()) {
|
|
101
|
-
paths.push(...(await
|
|
105
|
+
paths.push(...(await listMetadataFiles(sub)));
|
|
102
106
|
}
|
|
103
107
|
return paths;
|
|
104
108
|
}
|
|
109
|
+
function isMetadataFile(name) {
|
|
110
|
+
return name.endsWith(".json") || name.endsWith(".yaml") || name.endsWith(".yml");
|
|
111
|
+
}
|
|
105
112
|
//# sourceMappingURL=memory.js.map
|
package/dist/memory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACL,cAAc,EACd,YAAY,EACZ,iBAAiB,GAElB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAExE;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,cAAc,CAAC;AAEtD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;IACpC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC5B,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAE7B,0EAA0E;IAC1E,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtE,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC;QAChC,MAAM,KAAK,CAAC;IACd,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,4EAA4E;AAC5E,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IAClD,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,EAAE,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAE7C,iEAAiE;IACjE,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,cAAc,CAAC,CAAC;QACzE,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvE,MAAM,OAAO,GAAG,mBAAmB,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;YACxD,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,mEAAmE;gBACnE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBACxC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACL,cAAc,EACd,YAAY,EACZ,iBAAiB,GAElB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAExE;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,cAAc,CAAC;AAEtD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;IACpC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC5B,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAE7B,0EAA0E;IAC1E,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtE,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC;QAChC,MAAM,KAAK,CAAC;IACd,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,4EAA4E;AAC5E,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IAClD,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,EAAE,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAE7C,iEAAiE;IACjE,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,cAAc,CAAC,CAAC;QACzE,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvE,MAAM,OAAO,GAAG,mBAAmB,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;YACxD,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,mEAAmE;gBACnE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBACxC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;YAChF,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,OAAO,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,iBAAiB,CAAC,GAAW;IAC1C,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,KAAK,UAAU;YAAE,SAAS;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;aAAM,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,mEAAmE;IACnE,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACnF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metaobjectsdev/sdk",
|
|
3
|
-
"version": "0.7.0-rc.
|
|
3
|
+
"version": "0.7.0-rc.3",
|
|
4
4
|
"description": "Workspace helpers and agent-docs utilities for MetaObjects projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@metaobjectsdev/metadata": "0.7.0-rc.
|
|
41
|
+
"@metaobjectsdev/metadata": "0.7.0-rc.3",
|
|
42
42
|
"zod": "^3.23.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
package/src/forge-types.ts
CHANGED
|
@@ -104,6 +104,7 @@ export type ForgeAttr = (typeof FORGE_ATTRS)[number];
|
|
|
104
104
|
|
|
105
105
|
import {
|
|
106
106
|
type ChildRule,
|
|
107
|
+
type MetaDataTypeProvider,
|
|
107
108
|
type TypeDefinition,
|
|
108
109
|
TypeId,
|
|
109
110
|
TypeRegistry,
|
|
@@ -138,30 +139,47 @@ function def(
|
|
|
138
139
|
};
|
|
139
140
|
}
|
|
140
141
|
|
|
142
|
+
/**
|
|
143
|
+
* The Meta Forge provider — registers Meta Forge's five descriptive top-level
|
|
144
|
+
* types (decision, principle, convention, glossary, failure) plus their
|
|
145
|
+
* subtypes. Composed AFTER `metaobjects-core-types` so the structural attr
|
|
146
|
+
* type is available for forge child rules.
|
|
147
|
+
*
|
|
148
|
+
* Use via `composeRegistry([...coreProviders, forgeTypesProvider])` or via
|
|
149
|
+
* `loadMemory()`'s default bundle (forge is included by default).
|
|
150
|
+
*/
|
|
151
|
+
export const forgeTypesProvider: MetaDataTypeProvider = {
|
|
152
|
+
id: "metaobjects-forge",
|
|
153
|
+
dependencies: ["metaobjects-core-types"],
|
|
154
|
+
description: "Meta Forge descriptive top-level types (decision, principle, convention, glossary, failure).",
|
|
155
|
+
registerTypes(registry: TypeRegistry): void {
|
|
156
|
+
const forgeChildRules = [wildcardOf(TYPE_ATTR)];
|
|
157
|
+
|
|
158
|
+
for (const subType of FORGE_DECISION_SUBTYPES) {
|
|
159
|
+
registry.register(def(FORGE_TYPE_DECISION, subType, `Forge decision (${subType})`, forgeChildRules));
|
|
160
|
+
}
|
|
161
|
+
for (const subType of FORGE_PRINCIPLE_SUBTYPES) {
|
|
162
|
+
registry.register(def(FORGE_TYPE_PRINCIPLE, subType, `Forge principle (${subType})`, forgeChildRules));
|
|
163
|
+
}
|
|
164
|
+
for (const subType of FORGE_CONVENTION_SUBTYPES) {
|
|
165
|
+
registry.register(def(FORGE_TYPE_CONVENTION, subType, `Forge convention (${subType})`, forgeChildRules));
|
|
166
|
+
}
|
|
167
|
+
for (const subType of FORGE_GLOSSARY_SUBTYPES) {
|
|
168
|
+
registry.register(def(FORGE_TYPE_GLOSSARY, subType, `Forge glossary entry (${subType})`, forgeChildRules));
|
|
169
|
+
}
|
|
170
|
+
for (const subType of FORGE_FAILURE_SUBTYPES) {
|
|
171
|
+
registry.register(def(FORGE_TYPE_FAILURE, subType, `Forge failure record (${subType})`, forgeChildRules));
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
141
176
|
/**
|
|
142
177
|
* Register Meta Forge's five descriptive top-level types into the given
|
|
143
178
|
* registry. Must be called AFTER `registerCoreTypes()`.
|
|
144
179
|
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* of the metadata wrapper (unknowns are warned, not errored).
|
|
180
|
+
* Thin back-compat wrapper over `forgeTypesProvider.registerTypes`; prefer
|
|
181
|
+
* the provider directly for new code (composes correctly with other providers).
|
|
148
182
|
*/
|
|
149
183
|
export function registerForgeTypes(registry: TypeRegistry): void {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
for (const subType of FORGE_DECISION_SUBTYPES) {
|
|
153
|
-
registry.register(def(FORGE_TYPE_DECISION, subType, `Forge decision (${subType})`, forgeChildRules));
|
|
154
|
-
}
|
|
155
|
-
for (const subType of FORGE_PRINCIPLE_SUBTYPES) {
|
|
156
|
-
registry.register(def(FORGE_TYPE_PRINCIPLE, subType, `Forge principle (${subType})`, forgeChildRules));
|
|
157
|
-
}
|
|
158
|
-
for (const subType of FORGE_CONVENTION_SUBTYPES) {
|
|
159
|
-
registry.register(def(FORGE_TYPE_CONVENTION, subType, `Forge convention (${subType})`, forgeChildRules));
|
|
160
|
-
}
|
|
161
|
-
for (const subType of FORGE_GLOSSARY_SUBTYPES) {
|
|
162
|
-
registry.register(def(FORGE_TYPE_GLOSSARY, subType, `Forge glossary entry (${subType})`, forgeChildRules));
|
|
163
|
-
}
|
|
164
|
-
for (const subType of FORGE_FAILURE_SUBTYPES) {
|
|
165
|
-
registry.register(def(FORGE_TYPE_FAILURE, subType, `Forge failure record (${subType})`, forgeChildRules));
|
|
166
|
-
}
|
|
184
|
+
forgeTypesProvider.registerTypes(registry);
|
|
167
185
|
}
|
package/src/index.ts
CHANGED
|
@@ -70,15 +70,22 @@ export {
|
|
|
70
70
|
FORGE_ATTR_WHAT_WAS_TRIED,
|
|
71
71
|
FORGE_ATTR_WHY_IT_FAILED,
|
|
72
72
|
FORGE_ATTRS,
|
|
73
|
-
// Registration helper
|
|
73
|
+
// Registration helper + provider
|
|
74
74
|
registerForgeTypes,
|
|
75
|
+
forgeTypesProvider,
|
|
75
76
|
} from "./forge-types.js";
|
|
76
77
|
export type { ForgeType, ForgeAttr } from "./forge-types.js";
|
|
77
78
|
|
|
78
79
|
// Memory loader — read metaobjects/ into a MetaData tree
|
|
79
80
|
// (workspace-aware: walks extends: deps via pnpm-workspace.yaml or
|
|
80
81
|
// package.json workspaces field if present)
|
|
81
|
-
export {
|
|
82
|
+
export {
|
|
83
|
+
loadMemory,
|
|
84
|
+
defaultLoadMemoryProviders,
|
|
85
|
+
DEFAULT_METADATA_DIR,
|
|
86
|
+
DEFAULT_METAOBJECTS_DIR,
|
|
87
|
+
} from "./memory.js";
|
|
88
|
+
export type { LoadMemoryOptions } from "./memory.js";
|
|
82
89
|
|
|
83
90
|
// Workspace discovery — finds peer metadata packages in a monorepo
|
|
84
91
|
export { discoverWorkspace, resolveExtendsOrder, packageLabel } from "./workspace.js";
|
package/src/memory.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { readdir, stat } from "node:fs/promises";
|
|
3
3
|
import {
|
|
4
|
+
composeRegistry,
|
|
5
|
+
coreProviders,
|
|
4
6
|
MetaDataLoader,
|
|
5
|
-
|
|
6
|
-
registerCoreTypes,
|
|
7
|
+
type MetaDataTypeProvider,
|
|
7
8
|
type MetaRoot,
|
|
8
9
|
} from "@metaobjectsdev/metadata";
|
|
9
10
|
import { FileSource } from "@metaobjectsdev/metadata/core";
|
|
10
|
-
import {
|
|
11
|
+
import { forgeTypesProvider } from "./forge-types.js";
|
|
11
12
|
import { discoverWorkspace, resolveExtendsOrder } from "./workspace.js";
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -23,6 +24,36 @@ export const DEFAULT_METADATA_DIR = "metaobjects";
|
|
|
23
24
|
*/
|
|
24
25
|
export const DEFAULT_METAOBJECTS_DIR = ".metaobjects";
|
|
25
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Options for {@link loadMemory}. Consumers can supply additional
|
|
29
|
+
* {@link MetaDataTypeProvider}s to extend the metamodel with their own
|
|
30
|
+
* subtypes/attrs (e.g. a `template.toolcall` subtype).
|
|
31
|
+
*/
|
|
32
|
+
export interface LoadMemoryOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Consumer-supplied providers. Composed AFTER the default core providers
|
|
35
|
+
* (core-types + db + documentation + forge) unless `replaceDefaults: true`
|
|
36
|
+
* is set. Use this to register additional subtypes or extend existing
|
|
37
|
+
* ones without forking the loader.
|
|
38
|
+
*/
|
|
39
|
+
providers?: readonly MetaDataTypeProvider[];
|
|
40
|
+
/**
|
|
41
|
+
* Skip the default core providers; supply your own full set. Advanced —
|
|
42
|
+
* use only when you need to compose a custom metamodel from scratch.
|
|
43
|
+
* Throws if `providers` is absent or empty.
|
|
44
|
+
*/
|
|
45
|
+
replaceDefaults?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Default provider bundle threaded by {@link loadMemory} when no options
|
|
49
|
+
* override is supplied. Exposed for tests/inspection; callers shouldn't need
|
|
50
|
+
* to spread this manually — `loadMemory(root, { providers: [mine] })`
|
|
51
|
+
* composes `[...defaultLoadMemoryProviders, mine]` automatically. */
|
|
52
|
+
export const defaultLoadMemoryProviders: readonly MetaDataTypeProvider[] = [
|
|
53
|
+
...coreProviders,
|
|
54
|
+
forgeTypesProvider,
|
|
55
|
+
];
|
|
56
|
+
|
|
26
57
|
/**
|
|
27
58
|
* Load all metadata files from `<repoRoot>/metaobjects/` into a single
|
|
28
59
|
* MetaData. If `<repoRoot>/.meta/package.meta.json` declares `extends:` deps
|
|
@@ -31,18 +62,35 @@ export const DEFAULT_METAOBJECTS_DIR = ".metaobjects";
|
|
|
31
62
|
*
|
|
32
63
|
* Excludes `_pending/`. Registers metaobjects core types plus Meta Forge's
|
|
33
64
|
* descriptive top-level types (decision, principle, etc.) so mixed content
|
|
34
|
-
* parses without warnings.
|
|
65
|
+
* parses without warnings. Consumer-supplied providers (via
|
|
66
|
+
* {@link LoadMemoryOptions.providers}) are composed AFTER the defaults so
|
|
67
|
+
* they may depend on core/forge ids.
|
|
35
68
|
*
|
|
36
69
|
* Throws if `metaobjects/` doesn't exist (callers should run `meta init`).
|
|
37
70
|
*
|
|
38
71
|
* @param repoRoot The project's working-directory root (e.g. process.cwd()).
|
|
39
72
|
* `loadMemory` resolves `metaobjects/` and (if workspace-aware) the
|
|
40
73
|
* transitive `extends:` graph automatically.
|
|
74
|
+
* @param options Optional {@link LoadMemoryOptions} — supply additional
|
|
75
|
+
* providers or replace the default bundle entirely.
|
|
41
76
|
*/
|
|
42
|
-
export async function loadMemory(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
77
|
+
export async function loadMemory(
|
|
78
|
+
repoRoot: string,
|
|
79
|
+
options?: LoadMemoryOptions,
|
|
80
|
+
): Promise<MetaRoot> {
|
|
81
|
+
const extra = options?.providers ?? [];
|
|
82
|
+
let providers: readonly MetaDataTypeProvider[];
|
|
83
|
+
if (options?.replaceDefaults === true) {
|
|
84
|
+
if (extra.length === 0) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
"loadMemory: `replaceDefaults: true` requires at least one provider in `providers`.",
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
providers = extra;
|
|
90
|
+
} else {
|
|
91
|
+
providers = [...defaultLoadMemoryProviders, ...extra];
|
|
92
|
+
}
|
|
93
|
+
const registry = composeRegistry(providers);
|
|
46
94
|
|
|
47
95
|
// Collect all metadata file paths to load. Order matters for the parser's
|
|
48
96
|
// deferred-resolution pass (it parses in array order, then resolves supers
|
|
@@ -74,23 +122,27 @@ async function collectMetadataPaths(repoRoot: string): Promise<string[]> {
|
|
|
74
122
|
for (const pkg of ordered) {
|
|
75
123
|
// Each workspace package's metadata lives alongside its .meta/ dir
|
|
76
124
|
const pkgRoot = join(pkg.metaDir, "..");
|
|
77
|
-
paths.push(...(await
|
|
125
|
+
paths.push(...(await listMetadataFiles(join(pkgRoot, DEFAULT_METADATA_DIR))));
|
|
78
126
|
}
|
|
79
127
|
return paths;
|
|
80
128
|
}
|
|
81
129
|
}
|
|
82
130
|
|
|
83
131
|
// Single-package path: scan metaobjects/ at the project root
|
|
84
|
-
return
|
|
132
|
+
return listMetadataFiles(join(repoRoot, DEFAULT_METADATA_DIR));
|
|
85
133
|
}
|
|
86
134
|
|
|
87
135
|
/**
|
|
88
|
-
* Recursively list *.json
|
|
89
|
-
* any level. Subdirectories (e.g. projections/) are
|
|
90
|
-
* Files within a directory are sorted alphabetically for
|
|
91
|
-
* order; subdirectories are visited after files at the
|
|
136
|
+
* Recursively list metadata files (*.json, *.yaml, *.yml) under a directory,
|
|
137
|
+
* excluding _pending/ at any level. Subdirectories (e.g. projections/) are
|
|
138
|
+
* walked depth-first. Files within a directory are sorted alphabetically for
|
|
139
|
+
* deterministic load order; subdirectories are visited after files at the
|
|
140
|
+
* same level.
|
|
141
|
+
*
|
|
142
|
+
* Format selection (parsing) happens downstream in `FileSource` from
|
|
143
|
+
* `@metaobjectsdev/metadata`, which infers the parser from file extension.
|
|
92
144
|
*/
|
|
93
|
-
async function
|
|
145
|
+
async function listMetadataFiles(dir: string): Promise<string[]> {
|
|
94
146
|
let entries: string[];
|
|
95
147
|
try {
|
|
96
148
|
entries = await readdir(dir);
|
|
@@ -105,13 +157,17 @@ async function listJsonFiles(dir: string): Promise<string[]> {
|
|
|
105
157
|
const s = await stat(full);
|
|
106
158
|
if (s.isDirectory()) {
|
|
107
159
|
subdirs.push(full);
|
|
108
|
-
} else if (s.isFile() && entry
|
|
160
|
+
} else if (s.isFile() && isMetadataFile(entry)) {
|
|
109
161
|
paths.push(full);
|
|
110
162
|
}
|
|
111
163
|
}
|
|
112
164
|
// Recurse into subdirectories after collecting files at this level
|
|
113
165
|
for (const sub of subdirs.sort()) {
|
|
114
|
-
paths.push(...(await
|
|
166
|
+
paths.push(...(await listMetadataFiles(sub)));
|
|
115
167
|
}
|
|
116
168
|
return paths;
|
|
117
169
|
}
|
|
170
|
+
|
|
171
|
+
function isMetadataFile(name: string): boolean {
|
|
172
|
+
return name.endsWith(".json") || name.endsWith(".yaml") || name.endsWith(".yml");
|
|
173
|
+
}
|