@x12i/memorix-format 1.0.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.
Files changed (45) hide show
  1. package/README.md +90 -0
  2. package/dist/associated.d.ts +38 -0
  3. package/dist/associated.d.ts.map +1 -0
  4. package/dist/associated.js +59 -0
  5. package/dist/associated.js.map +1 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +199 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/concept.d.ts +16 -0
  11. package/dist/concept.d.ts.map +1 -0
  12. package/dist/concept.js +75 -0
  13. package/dist/concept.js.map +1 -0
  14. package/dist/constants.d.ts +21 -0
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/constants.js +49 -0
  17. package/dist/constants.js.map +1 -0
  18. package/dist/index.d.ts +9 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +7 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/inspect.d.ts +4 -0
  23. package/dist/inspect.d.ts.map +1 -0
  24. package/dist/inspect.js +51 -0
  25. package/dist/inspect.js.map +1 -0
  26. package/dist/types.d.ts +81 -0
  27. package/dist/types.d.ts.map +1 -0
  28. package/dist/types.js +2 -0
  29. package/dist/types.js.map +1 -0
  30. package/dist/utils.d.ts +6 -0
  31. package/dist/utils.d.ts.map +1 -0
  32. package/dist/utils.js +23 -0
  33. package/dist/utils.js.map +1 -0
  34. package/dist/validate.d.ts +14 -0
  35. package/dist/validate.d.ts.map +1 -0
  36. package/dist/validate.js +211 -0
  37. package/dist/validate.js.map +1 -0
  38. package/docs/association-format.md +466 -0
  39. package/docs/memorix-format-additions.md +956 -0
  40. package/docs/memorix-format-for-dummies-association-corrections.md +113 -0
  41. package/docs/memorix-format.md +282 -0
  42. package/docs/memorix-workflow-format.md +114 -0
  43. package/examples/invalid-record.json +11 -0
  44. package/examples/valid-snapshot.json +38 -0
  45. package/package.json +67 -0
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # @x12i/memorix-format
2
+
3
+ Memorix record format as an npm package: **types**, **validator**, **CLI**, and the **specification docs**.
4
+
5
+ Canonical envelope: [docs/memorix-format.md](./docs/memorix-format.md).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @x12i/memorix-format
11
+ ```
12
+
13
+ ## SDK
14
+
15
+ ```ts
16
+ import {
17
+ validateMemorixRecord,
18
+ inspectMemorixRecord,
19
+ buildConceptIdentifier,
20
+ buildAssociatedPropertyName,
21
+ } from "@x12i/memorix-format";
22
+
23
+ const result = validateMemorixRecord(record, { contentType: "snapshots" });
24
+ if (!result.ok) {
25
+ console.error(result.issues);
26
+ }
27
+
28
+ const id = buildConceptIdentifier("ipAddress", "10.100.18.64");
29
+ const prop = buildAssociatedPropertyName({
30
+ form: "content",
31
+ objectType: "vulnerabilities",
32
+ contentType: "analysis",
33
+ });
34
+ ```
35
+
36
+ ### Exports
37
+
38
+ | Import | Purpose |
39
+ |---|---|
40
+ | `@x12i/memorix-format` | Types, validate, inspect, concept + associated helpers |
41
+ | `@x12i/memorix-format/validate` | Validator only |
42
+ | `@x12i/memorix-format/types` | Type-only surface |
43
+
44
+ ### Validation rules (clean envelope)
45
+
46
+ - Required: `recordId`, `concept` (with `identifier` + `title`), `data` (object)
47
+ - `concept.identifier` requires `kind`, kind-named value, and `identifierKey`
48
+ - `analytics` / `enrichment` / `insights` must be objects when present
49
+ - `associated*` properties must be arrays of objects (omit when empty)
50
+ - Legacy roots (`identity`, root `lifecycle`, `sourceFacts`, …) are errors unless `--allow-legacy`
51
+ - With `--content-type` other than `snapshots`, associated*/analytics/enrichment/insights are rejected
52
+
53
+ ## CLI
54
+
55
+ ```bash
56
+ npx memorix-format validate ./record.json
57
+ npx memorix-format validate ./records.ndjson --content-type=snapshots --json
58
+ npx memorix-format inspect ./record.json
59
+ npx memorix-format docs
60
+ npx memorix-format docs memorix-format.md
61
+ ```
62
+
63
+ Exit codes: `0` ok, `1` validation failed, `2` usage/parse error.
64
+
65
+ ## Packaged documentation
66
+
67
+ | Doc | Topic |
68
+ |---|---|
69
+ | [memorix-format.md](./docs/memorix-format.md) | Canonical clean record envelope |
70
+ | [memorix-format-additions.md](./docs/memorix-format-additions.md) | `data` / `associatedData` / `analytics` / `insights` semantics |
71
+ | [association-format.md](./docs/association-format.md) | `associated*` naming and materialization |
72
+ | [memorix-workflow-format.md](./docs/memorix-workflow-format.md) | `memorix-workflow/1` |
73
+ | [memorix-format-for-dummies-association-corrections.md](./docs/memorix-format-for-dummies-association-corrections.md) | Association corrections |
74
+
75
+ ## Develop
76
+
77
+ ```bash
78
+ cd memorix-format
79
+ npm install
80
+ npm test
81
+ npm run build
82
+ ```
83
+
84
+ ## Publish
85
+
86
+ ```bash
87
+ cd memorix-format
88
+ npm run build && npm test
89
+ npm publish --access public
90
+ ```
@@ -0,0 +1,38 @@
1
+ export type AssociatedPropertyNameInput = {
2
+ form: "content";
3
+ objectType: string;
4
+ contentType: string;
5
+ top?: boolean;
6
+ } | {
7
+ form: "snapshotsRootProperty";
8
+ objectType: string;
9
+ rootProperty: string;
10
+ top?: boolean;
11
+ } | {
12
+ form: "enrichment";
13
+ objectType: string;
14
+ top?: boolean;
15
+ } | {
16
+ form: "concepts";
17
+ objectType: string;
18
+ top?: boolean;
19
+ } | {
20
+ form: "recordIds";
21
+ objectType: string;
22
+ top?: boolean;
23
+ };
24
+ /** True when a root key is an associated* property. */
25
+ export declare function isAssociatedPropertyName(name: string): boolean;
26
+ /** True when the property name follows the enrichment association convention. */
27
+ export declare function isEnrichmentAssociatedPropertyName(name: string): boolean;
28
+ /** True when the property name follows the ranked top association convention. */
29
+ export declare function isTopAssociatedPropertyName(name: string): boolean;
30
+ /** True for known legacy short associated names. */
31
+ export declare function isLegacyAssociatedPropertyName(name: string): boolean;
32
+ /** Build canonical v2 associated property name. */
33
+ export declare function buildAssociatedPropertyName(input: AssociatedPropertyNameInput): string;
34
+ /** Validate v2 associated property name conventions (throws on hard errors). */
35
+ export declare function assertAssociatedPropertyName(name: string): void;
36
+ /** List associated* keys present on a record root. */
37
+ export declare function listAssociatedProperties(record: Record<string, unknown>): string[];
38
+ //# sourceMappingURL=associated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"associated.d.ts","sourceRoot":"","sources":["../src/associated.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,2BAA2B,GACnC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1F;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7D,uDAAuD;AACvD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,iFAAiF;AACjF,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExE;AAED,iFAAiF;AACjF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED,oDAAoD;AACpD,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED,mDAAmD;AACnD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,2BAA2B,GAAG,MAAM,CAuBtF;AAED,gFAAgF;AAChF,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAO/D;AAED,sDAAsD;AACtD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAIlF"}
@@ -0,0 +1,59 @@
1
+ import { LEGACY_ASSOCIATED_NAMES } from "./constants.js";
2
+ import { pascalCaseObjectType } from "./utils.js";
3
+ /** True when a root key is an associated* property. */
4
+ export function isAssociatedPropertyName(name) {
5
+ return name.startsWith("associated");
6
+ }
7
+ /** True when the property name follows the enrichment association convention. */
8
+ export function isEnrichmentAssociatedPropertyName(name) {
9
+ return /^associated(?:Top)?[A-Z][A-Za-z0-9]*Enrichment$/.test(name);
10
+ }
11
+ /** True when the property name follows the ranked top association convention. */
12
+ export function isTopAssociatedPropertyName(name) {
13
+ return name.startsWith("associatedTop");
14
+ }
15
+ /** True for known legacy short associated names. */
16
+ export function isLegacyAssociatedPropertyName(name) {
17
+ return LEGACY_ASSOCIATED_NAMES.has(name);
18
+ }
19
+ /** Build canonical v2 associated property name. */
20
+ export function buildAssociatedPropertyName(input) {
21
+ const objectSegment = pascalCaseObjectType(input.objectType);
22
+ const topPrefix = input.top ? "Top" : "";
23
+ switch (input.form) {
24
+ case "content": {
25
+ const contentSegment = pascalCaseObjectType(input.contentType);
26
+ return `associated${topPrefix}${objectSegment}${contentSegment}`;
27
+ }
28
+ case "snapshotsRootProperty": {
29
+ const rootSegment = pascalCaseObjectType(input.rootProperty);
30
+ return `associated${topPrefix}${objectSegment}Snapshots${rootSegment}`;
31
+ }
32
+ case "enrichment":
33
+ return `associated${topPrefix}${objectSegment}Enrichment`;
34
+ case "concepts":
35
+ return `associated${topPrefix}${objectSegment}Concepts`;
36
+ case "recordIds":
37
+ return `associated${topPrefix}${objectSegment}RecordIds`;
38
+ default: {
39
+ const _exhaustive = input;
40
+ throw new Error(`Unsupported associated property name input: ${JSON.stringify(_exhaustive)}`);
41
+ }
42
+ }
43
+ }
44
+ /** Validate v2 associated property name conventions (throws on hard errors). */
45
+ export function assertAssociatedPropertyName(name) {
46
+ if (!name.startsWith("associated")) {
47
+ throw new Error(`Associated property must start with "associated": ${name}`);
48
+ }
49
+ if (name.includes("RecordsIds")) {
50
+ throw new Error(`Use "RecordIds" not "RecordsIds": ${name}`);
51
+ }
52
+ }
53
+ /** List associated* keys present on a record root. */
54
+ export function listAssociatedProperties(record) {
55
+ return Object.keys(record)
56
+ .filter(isAssociatedPropertyName)
57
+ .sort();
58
+ }
59
+ //# sourceMappingURL=associated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"associated.js","sourceRoot":"","sources":["../src/associated.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AASlD,uDAAuD;AACvD,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,kCAAkC,CAAC,IAAY;IAC7D,OAAO,iDAAiD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtE,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,2BAA2B,CAAC,IAAY;IACtD,OAAO,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AAC1C,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,8BAA8B,CAAC,IAAY;IACzD,OAAO,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,2BAA2B,CAAC,KAAkC;IAC5E,MAAM,aAAa,GAAG,oBAAoB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACzC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,cAAc,GAAG,oBAAoB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC/D,OAAO,aAAa,SAAS,GAAG,aAAa,GAAG,cAAc,EAAE,CAAC;QACnE,CAAC;QACD,KAAK,uBAAuB,CAAC,CAAC,CAAC;YAC7B,MAAM,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC7D,OAAO,aAAa,SAAS,GAAG,aAAa,YAAY,WAAW,EAAE,CAAC;QACzE,CAAC;QACD,KAAK,YAAY;YACf,OAAO,aAAa,SAAS,GAAG,aAAa,YAAY,CAAC;QAC5D,KAAK,UAAU;YACb,OAAO,aAAa,SAAS,GAAG,aAAa,UAAU,CAAC;QAC1D,KAAK,WAAW;YACd,OAAO,aAAa,SAAS,GAAG,aAAa,WAAW,CAAC;QAC3D,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,KAAK,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,4BAA4B,CAAC,IAAY;IACvD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,qDAAqD,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,wBAAwB,CAAC,MAA+B;IACtE,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SACvB,MAAM,CAAC,wBAAwB,CAAC;SAChC,IAAI,EAAE,CAAC;AACZ,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, existsSync, readdirSync } from "node:fs";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { createRequire } from "node:module";
6
+ import { inspectMemorixRecord } from "./inspect.js";
7
+ import { parseRecordsJson, validateMemorixRecord } from "./validate.js";
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const require = createRequire(import.meta.url);
10
+ function packageVersion() {
11
+ try {
12
+ const pkg = require(join(__dirname, "..", "package.json"));
13
+ return pkg.version ?? "0.0.0";
14
+ }
15
+ catch {
16
+ return "0.0.0";
17
+ }
18
+ }
19
+ function docsDir() {
20
+ const candidates = [
21
+ join(__dirname, "..", "docs"),
22
+ join(process.cwd(), "docs"),
23
+ ];
24
+ for (const dir of candidates) {
25
+ if (existsSync(dir))
26
+ return dir;
27
+ }
28
+ return candidates[0];
29
+ }
30
+ function printHelp() {
31
+ console.log(`memorix-format <command> [options]
32
+
33
+ Memorix record format SDK + CLI (validate, inspect, docs).
34
+
35
+ Commands:
36
+ validate [file|-] Validate JSON / JSON array / NDJSON records
37
+ inspect [file|-] Summarize buckets and associated properties
38
+ docs [name] List packaged specs, or print one by basename
39
+ version Print package version
40
+ help Show this help
41
+
42
+ Validate / inspect options:
43
+ --content-type=<ct> Hint content type (enforces snapshot-only buckets)
44
+ --allow-legacy Warn on legacy 2.0 roots instead of erroring
45
+ --strict Fail on warnings as well as errors
46
+ --json Machine-readable JSON output
47
+
48
+ Examples:
49
+ memorix-format validate ./record.json
50
+ memorix-format validate - --content-type=snapshots < records.ndjson
51
+ memorix-format inspect ./record.json --json
52
+ memorix-format docs memorix-format.md
53
+ `);
54
+ }
55
+ function readFlag(args, name) {
56
+ const prefix = `--${name}=`;
57
+ const hit = args.find((a) => a.startsWith(prefix));
58
+ return hit?.slice(prefix.length);
59
+ }
60
+ function hasFlag(args, name) {
61
+ return args.includes(`--${name}`);
62
+ }
63
+ function readInput(pathArg) {
64
+ const path = pathArg && pathArg !== "-" ? resolve(pathArg) : null;
65
+ if (path) {
66
+ return readFileSync(path, "utf8");
67
+ }
68
+ return readFileSync(0, "utf8");
69
+ }
70
+ function buildValidateOptions(args) {
71
+ return {
72
+ contentType: readFlag(args, "content-type"),
73
+ allowLegacyEnvelope: hasFlag(args, "allow-legacy"),
74
+ strict: hasFlag(args, "strict"),
75
+ };
76
+ }
77
+ function runValidate(args) {
78
+ const positional = args.filter((a) => !a.startsWith("--"));
79
+ const file = positional[0];
80
+ const options = buildValidateOptions(args);
81
+ const asJson = hasFlag(args, "json");
82
+ let records;
83
+ try {
84
+ records = parseRecordsJson(readInput(file));
85
+ }
86
+ catch (err) {
87
+ const message = err instanceof Error ? err.message : String(err);
88
+ console.error(`Failed to parse input: ${message}`);
89
+ return 2;
90
+ }
91
+ if (records.length === 0) {
92
+ console.error("No records found in input");
93
+ return 2;
94
+ }
95
+ const results = records.map((r, i) => ({
96
+ index: i,
97
+ ...validateMemorixRecord(r, options),
98
+ }));
99
+ const ok = results.every((r) => r.ok);
100
+ if (asJson) {
101
+ console.log(JSON.stringify({ ok, count: results.length, results }, null, 2));
102
+ }
103
+ else {
104
+ for (const r of results) {
105
+ const label = r.recordId ?? `#${r.index}`;
106
+ if (r.ok) {
107
+ console.log(`OK ${label}`);
108
+ }
109
+ else {
110
+ console.log(`FAIL ${label}`);
111
+ }
112
+ for (const issue of r.issues) {
113
+ console.log(` [${issue.severity}] ${issue.path}: ${issue.message} (${issue.code})`);
114
+ }
115
+ }
116
+ console.log(`${ok ? "Passed" : "Failed"}: ${results.filter((r) => r.ok).length}/${results.length}`);
117
+ }
118
+ return ok ? 0 : 1;
119
+ }
120
+ function runInspect(args) {
121
+ const positional = args.filter((a) => !a.startsWith("--"));
122
+ const file = positional[0];
123
+ const asJson = hasFlag(args, "json");
124
+ let records;
125
+ try {
126
+ records = parseRecordsJson(readInput(file));
127
+ }
128
+ catch (err) {
129
+ const message = err instanceof Error ? err.message : String(err);
130
+ console.error(`Failed to parse input: ${message}`);
131
+ return 2;
132
+ }
133
+ const inspections = records.map((r, i) => ({
134
+ index: i,
135
+ ...inspectMemorixRecord(r),
136
+ }));
137
+ if (asJson) {
138
+ console.log(JSON.stringify({ count: inspections.length, records: inspections }, null, 2));
139
+ return 0;
140
+ }
141
+ for (const row of inspections) {
142
+ console.log(`#${row.index} recordId=${row.recordId ?? "(missing)"} concept=${row.conceptKind ?? "-"} title=${row.conceptTitle ?? "-"}`);
143
+ console.log(` buckets: data=${row.buckets.data} analytics=${row.buckets.analytics} enrichment=${row.buckets.enrichment} insights=${row.buckets.insights} _system=${row.buckets.system}`);
144
+ console.log(` associated: ${row.associatedProperties.length ? row.associatedProperties.join(", ") : "(none)"}`);
145
+ if (row.legacyRoots.length)
146
+ console.log(` legacy roots: ${row.legacyRoots.join(", ")}`);
147
+ if (row.unknownRoots.length)
148
+ console.log(` unknown roots: ${row.unknownRoots.join(", ")}`);
149
+ }
150
+ return 0;
151
+ }
152
+ function runDocs(args) {
153
+ const dir = docsDir();
154
+ const name = args.find((a) => !a.startsWith("--"));
155
+ if (!existsSync(dir)) {
156
+ console.error(`Docs directory not found: ${dir}`);
157
+ return 1;
158
+ }
159
+ if (!name) {
160
+ console.log(`Packaged Memorix format docs (${dir}):`);
161
+ for (const file of readdirSync(dir).sort()) {
162
+ if (file.endsWith(".md"))
163
+ console.log(` ${file}`);
164
+ }
165
+ return 0;
166
+ }
167
+ const base = name.endsWith(".md") ? name : `${name}.md`;
168
+ const path = join(dir, base);
169
+ if (!existsSync(path)) {
170
+ console.error(`Doc not found: ${base}`);
171
+ console.error(`Available: ${readdirSync(dir).filter((f) => f.endsWith(".md")).join(", ")}`);
172
+ return 1;
173
+ }
174
+ process.stdout.write(readFileSync(path, "utf8"));
175
+ return 0;
176
+ }
177
+ async function main(argv) {
178
+ const [cmd, ...args] = argv;
179
+ if (!cmd || cmd === "help" || cmd === "--help" || cmd === "-h") {
180
+ printHelp();
181
+ return cmd ? 0 : 1;
182
+ }
183
+ if (cmd === "version" || cmd === "--version" || cmd === "-v") {
184
+ console.log(packageVersion());
185
+ return 0;
186
+ }
187
+ if (cmd === "validate")
188
+ return runValidate(args);
189
+ if (cmd === "inspect")
190
+ return runInspect(args);
191
+ if (cmd === "docs")
192
+ return runDocs(args);
193
+ console.error(`Unknown command: ${cmd}`);
194
+ printHelp();
195
+ return 2;
196
+ }
197
+ const exitCode = await main(process.argv.slice(2));
198
+ process.exit(exitCode);
199
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { JsonObject, MemorixConceptIdentifier } from "./types.js";
2
+ /**
3
+ * Build deterministic identity string from an identifier object.
4
+ * Joins kind and value fields with ":" (e.g. ipAddress:10.100.18.64).
5
+ */
6
+ export declare function buildIdentityString(identifier: Record<string, unknown>): string | null;
7
+ /** Build a clean concept identifier with identifierKey. */
8
+ export declare function buildConceptIdentifier(kind: string, value: string, extra?: Record<string, string>): MemorixConceptIdentifier;
9
+ /** Read logical record id (clean root, then legacy identity block). */
10
+ export declare function readRecordId(record: JsonObject): string;
11
+ export declare function readConceptIdentifier(record: JsonObject): {
12
+ kind: string;
13
+ value: string;
14
+ } | null;
15
+ export declare function readConceptTitle(record: JsonObject): string | undefined;
16
+ //# sourceMappingURL=concept.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concept.d.ts","sourceRoot":"","sources":["../src/concept.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAGvE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAYtF;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACjC,wBAAwB,CAU1B;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAYvD;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,UAAU,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAmBxC;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAOvE"}
@@ -0,0 +1,75 @@
1
+ import { isPlainObject, stringifyId } from "./utils.js";
2
+ /**
3
+ * Build deterministic identity string from an identifier object.
4
+ * Joins kind and value fields with ":" (e.g. ipAddress:10.100.18.64).
5
+ */
6
+ export function buildIdentityString(identifier) {
7
+ const kind = stringifyId(identifier.kind);
8
+ if (!kind)
9
+ return null;
10
+ if (identifier[kind] != null) {
11
+ return `${kind}:${String(identifier[kind])}`;
12
+ }
13
+ const parts = Object.keys(identifier)
14
+ .filter((key) => key !== "kind" && key !== "identifierKey")
15
+ .sort()
16
+ .map((key) => String(identifier[key]));
17
+ if (parts.length === 0)
18
+ return null;
19
+ return [kind, ...parts].join(":");
20
+ }
21
+ /** Build a clean concept identifier with identifierKey. */
22
+ export function buildConceptIdentifier(kind, value, extra = {}) {
23
+ const identifier = {
24
+ kind,
25
+ [kind]: value,
26
+ ...extra,
27
+ identifierKey: "",
28
+ };
29
+ const key = buildIdentityString(identifier);
30
+ identifier.identifierKey = key ?? `${kind}:${value}`;
31
+ return identifier;
32
+ }
33
+ /** Read logical record id (clean root, then legacy identity block). */
34
+ export function readRecordId(record) {
35
+ const root = stringifyId(record.recordId);
36
+ if (root)
37
+ return root;
38
+ const identity = record.identity;
39
+ if (isPlainObject(identity)) {
40
+ return (stringifyId(identity.recordId) ??
41
+ stringifyId(identity.targetId) ??
42
+ "");
43
+ }
44
+ return stringifyId(record._id) ?? "";
45
+ }
46
+ export function readConceptIdentifier(record) {
47
+ const concept = record.concept;
48
+ if (!isPlainObject(concept))
49
+ return null;
50
+ const identifier = concept.identifier;
51
+ if (isPlainObject(identifier)) {
52
+ const kind = stringifyId(identifier.kind);
53
+ if (kind && identifier[kind] != null) {
54
+ return { kind, value: String(identifier[kind]) };
55
+ }
56
+ }
57
+ // Legacy concept.name
58
+ const name = concept.name;
59
+ if (typeof name === "string" && name.trim()) {
60
+ const kind = stringifyId(concept.kind) ?? "name";
61
+ return { kind, value: name.trim() };
62
+ }
63
+ return null;
64
+ }
65
+ export function readConceptTitle(record) {
66
+ const concept = record.concept;
67
+ if (!isPlainObject(concept))
68
+ return undefined;
69
+ const title = stringifyId(concept.title);
70
+ if (title)
71
+ return title;
72
+ const id = readConceptIdentifier(record);
73
+ return id?.value;
74
+ }
75
+ //# sourceMappingURL=concept.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concept.js","sourceRoot":"","sources":["../src/concept.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /** Canonical clean-envelope field names. */
2
+ export declare const RECORD_ID_FIELD: "recordId";
3
+ export declare const CONCEPT_FIELD: "concept";
4
+ export declare const DATA_FIELD: "data";
5
+ export declare const ANALYTICS_FIELD: "analytics";
6
+ export declare const ENRICHMENT_FIELD: "enrichment";
7
+ export declare const INSIGHTS_FIELD: "insights";
8
+ export declare const SYSTEM_FIELD: "_system";
9
+ export declare const GRAPH_RUNS_FIELD: "_system._graphRuns";
10
+ export declare const JOB_TYPE_RUNS_FIELD: "_system._jobTypeRuns";
11
+ export declare const SYSTEM_LIFECYCLE_FIELD: "_system.lifecycle";
12
+ /** Reserved root keys that are not associated* properties. */
13
+ export declare const CANONICAL_ROOT_KEYS: Set<string>;
14
+ /** Legacy Memorix 2.0 roots removed from the clean envelope. */
15
+ export declare const LEGACY_ROOT_KEYS: Set<string>;
16
+ /** Snapshot-only consumption buckets (clean format + additions appendix). */
17
+ export declare const SNAPSHOT_ONLY_BUCKETS: readonly ["analytics", "enrichment", "insights"];
18
+ /** Known legacy short associated property names. */
19
+ export declare const LEGACY_ASSOCIATED_NAMES: Set<string>;
20
+ export declare const DEFAULT_TOP_ASSOCIATED_ITEMS = 5;
21
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,eAAO,MAAM,eAAe,EAAG,UAAmB,CAAC;AACnD,eAAO,MAAM,aAAa,EAAG,SAAkB,CAAC;AAChD,eAAO,MAAM,UAAU,EAAG,MAAe,CAAC;AAC1C,eAAO,MAAM,eAAe,EAAG,WAAoB,CAAC;AACpD,eAAO,MAAM,gBAAgB,EAAG,YAAqB,CAAC;AACtD,eAAO,MAAM,cAAc,EAAG,UAAmB,CAAC;AAClD,eAAO,MAAM,YAAY,EAAG,SAAkB,CAAC;AAE/C,eAAO,MAAM,gBAAgB,EAAG,oBAA6B,CAAC;AAC9D,eAAO,MAAM,mBAAmB,EAAG,sBAA+B,CAAC;AACnE,eAAO,MAAM,sBAAsB,EAAG,mBAA4B,CAAC;AAEnE,8DAA8D;AAC9D,eAAO,MAAM,mBAAmB,aAS9B,CAAC;AAEH,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,aAO3B,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,kDAIxB,CAAC;AAEX,oDAAoD;AACpD,eAAO,MAAM,uBAAuB,aAQlC,CAAC;AAEH,eAAO,MAAM,4BAA4B,IAAI,CAAC"}
@@ -0,0 +1,49 @@
1
+ /** Canonical clean-envelope field names. */
2
+ export const RECORD_ID_FIELD = "recordId";
3
+ export const CONCEPT_FIELD = "concept";
4
+ export const DATA_FIELD = "data";
5
+ export const ANALYTICS_FIELD = "analytics";
6
+ export const ENRICHMENT_FIELD = "enrichment";
7
+ export const INSIGHTS_FIELD = "insights";
8
+ export const SYSTEM_FIELD = "_system";
9
+ export const GRAPH_RUNS_FIELD = "_system._graphRuns";
10
+ export const JOB_TYPE_RUNS_FIELD = "_system._jobTypeRuns";
11
+ export const SYSTEM_LIFECYCLE_FIELD = "_system.lifecycle";
12
+ /** Reserved root keys that are not associated* properties. */
13
+ export const CANONICAL_ROOT_KEYS = new Set([
14
+ "_id",
15
+ RECORD_ID_FIELD,
16
+ CONCEPT_FIELD,
17
+ DATA_FIELD,
18
+ ANALYTICS_FIELD,
19
+ ENRICHMENT_FIELD,
20
+ INSIGHTS_FIELD,
21
+ SYSTEM_FIELD,
22
+ ]);
23
+ /** Legacy Memorix 2.0 roots removed from the clean envelope. */
24
+ export const LEGACY_ROOT_KEYS = new Set([
25
+ "identity",
26
+ "lifecycle",
27
+ "sourceFacts",
28
+ "index",
29
+ "_graphRuns",
30
+ "_jobTypeRuns",
31
+ ]);
32
+ /** Snapshot-only consumption buckets (clean format + additions appendix). */
33
+ export const SNAPSHOT_ONLY_BUCKETS = [
34
+ ANALYTICS_FIELD,
35
+ ENRICHMENT_FIELD,
36
+ INSIGHTS_FIELD,
37
+ ];
38
+ /** Known legacy short associated property names. */
39
+ export const LEGACY_ASSOCIATED_NAMES = new Set([
40
+ "associatedData",
41
+ "associatedDiscovery",
42
+ "associatedAnalysis",
43
+ "associatedSiblings",
44
+ "associatedChildren",
45
+ "associatedAssets",
46
+ "associatedSubnets",
47
+ ]);
48
+ export const DEFAULT_TOP_ASSOCIATED_ITEMS = 5;
49
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,CAAC,MAAM,eAAe,GAAG,UAAmB,CAAC;AACnD,MAAM,CAAC,MAAM,aAAa,GAAG,SAAkB,CAAC;AAChD,MAAM,CAAC,MAAM,UAAU,GAAG,MAAe,CAAC;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,WAAoB,CAAC;AACpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAqB,CAAC;AACtD,MAAM,CAAC,MAAM,cAAc,GAAG,UAAmB,CAAC;AAClD,MAAM,CAAC,MAAM,YAAY,GAAG,SAAkB,CAAC;AAE/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,oBAA6B,CAAC;AAC9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,sBAA+B,CAAC;AACnE,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAA4B,CAAC;AAEnE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IACzC,KAAK;IACL,eAAe;IACf,aAAa;IACb,UAAU;IACV,eAAe;IACf,gBAAgB;IAChB,cAAc;IACd,YAAY;CACb,CAAC,CAAC;AAEH,gEAAgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IACtC,UAAU;IACV,WAAW;IACX,aAAa;IACb,OAAO;IACP,YAAY;IACZ,cAAc;CACf,CAAC,CAAC;AAEH,6EAA6E;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,eAAe;IACf,gBAAgB;IAChB,cAAc;CACN,CAAC;AAEX,oDAAoD;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IAC7C,gBAAgB;IAChB,qBAAqB;IACrB,oBAAoB;IACpB,oBAAoB;IACpB,oBAAoB;IACpB,kBAAkB;IAClB,mBAAmB;CACpB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type { JsonObject, MemorixConcept, MemorixConceptIdentifier, MemorixContentTypeHint, MemorixLifecycleEvent, MemorixRecord, MemorixSystemBlock, RecordInspection, ValidateRecordOptions, ValidateRecordResult, ValidationIssue, ValidationSeverity, } from "./types.js";
2
+ export { ANALYTICS_FIELD, CANONICAL_ROOT_KEYS, CONCEPT_FIELD, DATA_FIELD, DEFAULT_TOP_ASSOCIATED_ITEMS, ENRICHMENT_FIELD, GRAPH_RUNS_FIELD, INSIGHTS_FIELD, JOB_TYPE_RUNS_FIELD, LEGACY_ASSOCIATED_NAMES, LEGACY_ROOT_KEYS, RECORD_ID_FIELD, SNAPSHOT_ONLY_BUCKETS, SYSTEM_FIELD, SYSTEM_LIFECYCLE_FIELD, } from "./constants.js";
3
+ export { assertAssociatedPropertyName, buildAssociatedPropertyName, isAssociatedPropertyName, isEnrichmentAssociatedPropertyName, isLegacyAssociatedPropertyName, isTopAssociatedPropertyName, listAssociatedProperties, } from "./associated.js";
4
+ export type { AssociatedPropertyNameInput } from "./associated.js";
5
+ export { buildConceptIdentifier, buildIdentityString, readConceptIdentifier, readConceptTitle, readRecordId, } from "./concept.js";
6
+ export { inspectMemorixRecord } from "./inspect.js";
7
+ export { parseRecordsJson, validateMemorixRecord, validateMemorixRecords, } from "./validate.js";
8
+ export { isPlainObject, pascalCaseObjectType, stringifyId } from "./utils.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,UAAU,EACV,4BAA4B,EAC5B,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,kCAAkC,EAClC,8BAA8B,EAC9B,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { ANALYTICS_FIELD, CANONICAL_ROOT_KEYS, CONCEPT_FIELD, DATA_FIELD, DEFAULT_TOP_ASSOCIATED_ITEMS, ENRICHMENT_FIELD, GRAPH_RUNS_FIELD, INSIGHTS_FIELD, JOB_TYPE_RUNS_FIELD, LEGACY_ASSOCIATED_NAMES, LEGACY_ROOT_KEYS, RECORD_ID_FIELD, SNAPSHOT_ONLY_BUCKETS, SYSTEM_FIELD, SYSTEM_LIFECYCLE_FIELD, } from "./constants.js";
2
+ export { assertAssociatedPropertyName, buildAssociatedPropertyName, isAssociatedPropertyName, isEnrichmentAssociatedPropertyName, isLegacyAssociatedPropertyName, isTopAssociatedPropertyName, listAssociatedProperties, } from "./associated.js";
3
+ export { buildConceptIdentifier, buildIdentityString, readConceptIdentifier, readConceptTitle, readRecordId, } from "./concept.js";
4
+ export { inspectMemorixRecord } from "./inspect.js";
5
+ export { parseRecordsJson, validateMemorixRecord, validateMemorixRecords, } from "./validate.js";
6
+ export { isPlainObject, pascalCaseObjectType, stringifyId } from "./utils.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,UAAU,EACV,4BAA4B,EAC5B,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,kCAAkC,EAClC,8BAA8B,EAC9B,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { RecordInspection } from "./types.js";
2
+ /** Summarize which format buckets and associated properties a record uses. */
3
+ export declare function inspectMemorixRecord(input: unknown): RecordInspection;
4
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAc,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG/D,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CA8CrE"}