@platformos/platformos-graph 0.0.19 → 0.1.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 +516 -0
- package/bin/platformos-graph +21 -81
- package/dist/cache-probes.spec.d.ts +1 -0
- package/dist/cache-probes.spec.js +62 -0
- package/dist/cache-probes.spec.js.map +1 -0
- package/dist/cli.d.ts +46 -0
- package/dist/cli.js +131 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.spec.d.ts +1 -0
- package/dist/cli.spec.js +235 -0
- package/dist/cli.spec.js.map +1 -0
- package/dist/graph/app-index-resolution.spec.d.ts +1 -0
- package/dist/graph/app-index-resolution.spec.js +167 -0
- package/dist/graph/app-index-resolution.spec.js.map +1 -0
- package/dist/graph/asset-resolution.spec.d.ts +1 -0
- package/dist/graph/asset-resolution.spec.js +64 -0
- package/dist/graph/asset-resolution.spec.js.map +1 -0
- package/dist/graph/augment.js +3 -1
- package/dist/graph/augment.js.map +1 -1
- package/dist/graph/build.d.ts +15 -2
- package/dist/graph/build.js +54 -12
- package/dist/graph/build.js.map +1 -1
- package/dist/graph/build.spec.d.ts +1 -0
- package/dist/graph/build.spec.js +138 -0
- package/dist/graph/build.spec.js.map +1 -0
- package/dist/graph/edge-sources.d.ts +28 -0
- package/dist/graph/edge-sources.js +43 -0
- package/dist/graph/edge-sources.js.map +1 -0
- package/dist/graph/edge-sources.spec.d.ts +1 -0
- package/dist/graph/edge-sources.spec.js +125 -0
- package/dist/graph/edge-sources.spec.js.map +1 -0
- package/dist/graph/extract.spec.d.ts +1 -0
- package/dist/graph/extract.spec.js +163 -0
- package/dist/graph/extract.spec.js.map +1 -0
- package/dist/graph/module.d.ts +70 -2
- package/dist/graph/module.js +164 -29
- package/dist/graph/module.js.map +1 -1
- package/dist/graph/module.spec.d.ts +1 -0
- package/dist/graph/module.spec.js +74 -0
- package/dist/graph/module.spec.js.map +1 -0
- package/dist/graph/query.d.ts +72 -0
- package/dist/graph/query.js +140 -0
- package/dist/graph/query.js.map +1 -0
- package/dist/graph/query.spec.d.ts +1 -0
- package/dist/graph/query.spec.js +209 -0
- package/dist/graph/query.spec.js.map +1 -0
- package/dist/graph/serialize.spec.d.ts +1 -0
- package/dist/graph/serialize.spec.js +50 -0
- package/dist/graph/serialize.spec.js.map +1 -0
- package/dist/graph/structural.spec.d.ts +1 -0
- package/dist/graph/structural.spec.js +146 -0
- package/dist/graph/structural.spec.js.map +1 -0
- package/dist/graph/test-helpers.d.ts +2 -3
- package/dist/graph/test-helpers.js +5 -9
- package/dist/graph/test-helpers.js.map +1 -1
- package/dist/graph/traverse-edges.spec.d.ts +1 -0
- package/dist/graph/traverse-edges.spec.js +337 -0
- package/dist/graph/traverse-edges.spec.js.map +1 -0
- package/dist/graph/traverse.d.ts +63 -4
- package/dist/graph/traverse.js +364 -49
- package/dist/graph/traverse.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +21 -4
- package/dist/index.js.map +1 -1
- package/dist/parsers.d.ts +35 -0
- package/dist/parsers.js +72 -0
- package/dist/parsers.js.map +1 -0
- package/dist/parsers.spec.d.ts +1 -0
- package/dist/parsers.spec.js +70 -0
- package/dist/parsers.spec.js.map +1 -0
- package/dist/toSourceCode.d.ts +14 -2
- package/dist/toSourceCode.js +23 -19
- package/dist/toSourceCode.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +114 -20
- package/dist/types.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/fixtures/asset-edges/app/assets/logo.css +1 -0
- package/fixtures/asset-edges/app/assets/site/app.js +1 -0
- package/fixtures/asset-edges/app/views/pages/index.liquid +3 -0
- package/fixtures/background-edges/app/views/pages/broken.liquid +3 -0
- package/fixtures/background-edges/app/views/pages/index.liquid +3 -0
- package/fixtures/background-edges/app/views/partials/jobs/notify.liquid +3 -0
- package/fixtures/function-edges/app/lib/queries/list.liquid +3 -0
- package/fixtures/function-edges/app/views/pages/broken.liquid +3 -0
- package/fixtures/function-edges/app/views/pages/index.liquid +3 -0
- package/fixtures/graphql-edges/app/graphql/blog_posts/find.graphql +10 -0
- package/fixtures/graphql-edges/app/views/pages/broken.liquid +3 -0
- package/fixtures/graphql-edges/app/views/pages/index.liquid +3 -0
- package/fixtures/graphql-table/app/graphql/with_table.graphql +5 -0
- package/fixtures/graphql-table/app/graphql/without_table.graphql +3 -0
- package/fixtures/graphql-table/app/views/pages/index.liquid +4 -0
- package/fixtures/include-edges/app/views/pages/index.liquid +1 -0
- package/fixtures/include-edges/app/views/partials/shared/header.liquid +1 -0
- package/fixtures/layout-edges/app/views/layouts/theme.liquid +4 -0
- package/fixtures/layout-edges/app/views/pages/broken.liquid +5 -0
- package/fixtures/layout-edges/app/views/pages/index.liquid +5 -0
- package/fixtures/module-edges/app/views/pages/index.liquid +4 -0
- package/fixtures/module-edges/modules/my_module/public/lib/queries/get.liquid +3 -0
- package/fixtures/module-edges/modules/my_module/public/views/partials/card.liquid +1 -0
- package/fixtures/schema-nodes/app/schema/blog_post.yml +6 -0
- package/fixtures/schema-nodes/app/schema/no_name.yml +3 -0
- package/fixtures/schema-nodes/app/views/pages/index.liquid +1 -0
- package/fixtures/skeleton/app/assets/app.js +1 -0
- package/fixtures/skeleton/app/views/partials/child.liquid +2 -4
- package/fixtures/skeleton/app/views/partials/parent.liquid +2 -4
- package/fixtures/structural/app/views/pages/about.liquid +1 -0
- package/fixtures/structural/app/views/pages/blog/show.liquid +4 -0
- package/fixtures/structural/app/views/pages/index.liquid +6 -0
- package/fixtures/structural/app/views/pages/rich.liquid +8 -0
- package/fixtures/structural/app/views/partials/card.liquid +1 -0
- package/fixtures/structural/app/views/partials/documented.liquid +5 -0
- package/package.json +7 -5
- package/src/cli.spec.ts +271 -0
- package/src/cli.ts +167 -0
- package/src/graph/augment.ts +4 -2
- package/src/graph/build.spec.ts +888 -9
- package/src/graph/build.ts +68 -17
- package/src/graph/edge-sources.spec.ts +125 -0
- package/src/graph/edge-sources.ts +49 -0
- package/src/graph/module.spec.ts +168 -0
- package/src/graph/module.ts +167 -33
- package/src/graph/query.spec.ts +260 -0
- package/src/graph/query.ts +154 -0
- package/src/graph/serialize.spec.ts +4 -4
- package/src/graph/test-helpers.ts +5 -12
- package/src/graph/traverse.spec.ts +278 -0
- package/src/graph/traverse.ts +423 -54
- package/src/index.ts +16 -1
- package/src/parsers.spec.ts +85 -0
- package/src/parsers.ts +75 -0
- package/src/toSourceCode.ts +26 -26
- package/src/types.ts +120 -23
- package/src/utils/index.ts +1 -1
- package/bin/jsconfig.json +0 -18
- package/dist/getWebComponentMap.d.ts +0 -10
- package/dist/getWebComponentMap.js +0 -66
- package/dist/getWebComponentMap.js.map +0 -1
- package/fixtures/skeleton/assets/app.js +0 -7
- package/src/getWebComponentMap.ts +0 -81
- /package/fixtures/skeleton/{assets → app/assets}/app.css +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-sources.js","sourceRoot":"","sources":["../../src/graph/edge-sources.ts"],"names":[],"mappings":";;AAiBA,oCASC;AAiBD,oDAKC;AA/CD,qEAKuC;AAEvC;;;;;;;;GAQG;AACH,SAAgB,YAAY,CAAC,GAAc,EAAE,OAAkB;IAC7D,QAAQ,IAAA,+BAAW,EAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;QAClC,KAAK,sCAAkB,CAAC,MAAM,CAAC;QAC/B,KAAK,sCAAkB,CAAC,IAAI,CAAC;QAC7B,KAAK,sCAAkB,CAAC,OAAO;YAC7B,OAAO,IAAI,CAAC;QACd;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACI,KAAK,UAAU,oBAAoB,CACxC,EAAsB,EACtB,OAAkB;IAElB,OAAO,IAAA,sCAAkB,EAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AAChF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const platformos_check_common_1 = require("@platformos/platformos-check-common");
|
|
5
|
+
const platformos_common_1 = require("@platformos/platformos-common");
|
|
6
|
+
const test_1 = require("@platformos/platformos-check-common/dist/test");
|
|
7
|
+
const index_1 = require("../index");
|
|
8
|
+
/**
|
|
9
|
+
* TASK-9.17: `enumerateEdgeSources` is the SINGLE canonical "what are the
|
|
10
|
+
* edge-source liquid files under a project root" primitive. The supervisor's
|
|
11
|
+
* GraphCache consumes it for BOTH the fingerprint domain and the build's entry
|
|
12
|
+
* points, so its definition must never silently drift from the file-type
|
|
13
|
+
* classifier (`getFileType` ← `FILE_TYPE_DIRS`).
|
|
14
|
+
*
|
|
15
|
+
* The load-bearing guard is EQUIVALENCE-TO-THE-CLASSIFIER: the SCOPED walk (only
|
|
16
|
+
* `APP_SOURCE_SUBTREES`, the TASK-9.15 Phase-3A perf win) must gather the exact
|
|
17
|
+
* same set a WHOLE-TREE walk filtered by `isEdgeSource` would. If a partial
|
|
18
|
+
* location is added to the classifier but its subtree is not walkable, the
|
|
19
|
+
* whole-tree walk finds files the scoped walk misses → this test fails, catching
|
|
20
|
+
* the drift before it under-reports dependents.
|
|
21
|
+
*/
|
|
22
|
+
(0, vitest_1.describe)('Unit: enumerateEdgeSources (canonical edge-source enumeration)', () => {
|
|
23
|
+
const rootUri = platformos_check_common_1.path.normalize('file:/');
|
|
24
|
+
const uri = (rel) => platformos_check_common_1.path.join(rootUri, rel);
|
|
25
|
+
// Edge sources under every canonical location a Page/Layout/Partial can live.
|
|
26
|
+
const EDGE_SOURCES = [
|
|
27
|
+
'app/views/pages/home.liquid', // Page (modern app/ root)
|
|
28
|
+
'app/views/layouts/application.liquid', // Layout
|
|
29
|
+
'app/views/partials/card.liquid', // Partial (views/partials)
|
|
30
|
+
'app/lib/helper.liquid', // Partial (lib)
|
|
31
|
+
'marketplace_builder/views/pages/legacy.liquid', // Page (legacy root)
|
|
32
|
+
'modules/shop/public/views/partials/widget.liquid', // Partial (top-level module, public)
|
|
33
|
+
'modules/shop/private/lib/secret.liquid', // Partial (top-level module, PRIVATE access level)
|
|
34
|
+
'app/modules/blog/private/views/pages/post.liquid', // Page (nested app/modules)
|
|
35
|
+
];
|
|
36
|
+
// Files that are NOT edge sources: leaves, non-liquid, and a bundled
|
|
37
|
+
// non-platformOS sibling that must never be walked.
|
|
38
|
+
const NON_EDGE_SOURCES = {
|
|
39
|
+
'app/graphql/get_posts.graphql': 'query { records { results { id } } }',
|
|
40
|
+
'app/schema/blog_post.yml': 'name: blog_post',
|
|
41
|
+
'app/assets/logo.css': 'body {}',
|
|
42
|
+
'react-app/src/components/Widget.liquid': 'noise that is never a source',
|
|
43
|
+
'README.md': '# project',
|
|
44
|
+
};
|
|
45
|
+
const makeFs = () => {
|
|
46
|
+
const files = { ...NON_EDGE_SOURCES };
|
|
47
|
+
for (const rel of EDGE_SOURCES)
|
|
48
|
+
files[rel] = '<div></div>';
|
|
49
|
+
return new test_1.MockFileSystem(files, rootUri);
|
|
50
|
+
};
|
|
51
|
+
const sorted = (uris) => [...uris].sort();
|
|
52
|
+
(0, vitest_1.it)('gathers exactly the edge sources across all source roots (nothing else)', async () => {
|
|
53
|
+
const fs = makeFs();
|
|
54
|
+
(0, vitest_1.expect)(sorted(await (0, index_1.enumerateEdgeSources)(fs, rootUri))).toEqual(sorted(EDGE_SOURCES.map(uri)));
|
|
55
|
+
});
|
|
56
|
+
(0, vitest_1.it)('the scoped walk equals a whole-tree walk filtered by the classifier (no drift)', async () => {
|
|
57
|
+
const fs = makeFs();
|
|
58
|
+
const scoped = sorted(await (0, index_1.enumerateEdgeSources)(fs, rootUri));
|
|
59
|
+
const wholeTree = sorted((await everyFileUnder(fs, rootUri)).filter((u) => (0, index_1.isEdgeSource)(u, rootUri)));
|
|
60
|
+
(0, vitest_1.expect)(scoped).toEqual(wholeTree);
|
|
61
|
+
});
|
|
62
|
+
(0, vitest_1.it)('isEdgeSource is exactly the Layout/Page/Partial classification', () => {
|
|
63
|
+
const EDGE_SOURCE_TYPES = [
|
|
64
|
+
platformos_common_1.PlatformOSFileType.Layout,
|
|
65
|
+
platformos_common_1.PlatformOSFileType.Page,
|
|
66
|
+
platformos_common_1.PlatformOSFileType.Partial,
|
|
67
|
+
];
|
|
68
|
+
for (const rel of EDGE_SOURCES) {
|
|
69
|
+
const u = uri(rel);
|
|
70
|
+
(0, vitest_1.expect)((0, index_1.isEdgeSource)(u, rootUri)).toBe(true);
|
|
71
|
+
(0, vitest_1.expect)(EDGE_SOURCE_TYPES).toContain((0, platformos_common_1.getFileType)(u, rootUri));
|
|
72
|
+
}
|
|
73
|
+
for (const rel of Object.keys(NON_EDGE_SOURCES)) {
|
|
74
|
+
const u = uri(rel);
|
|
75
|
+
(0, vitest_1.expect)((0, index_1.isEdgeSource)(u, rootUri)).toBe(false);
|
|
76
|
+
(0, vitest_1.expect)(EDGE_SOURCE_TYPES).not.toContain((0, platformos_common_1.getFileType)(u, rootUri));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
/**
|
|
80
|
+
* The reason the classification is anchored on the root. Unanchored, a directory
|
|
81
|
+
* named like a platformOS one ANYWHERE in the path classified: these three files
|
|
82
|
+
* are not part of the app, and counting them in the fingerprint domain made the
|
|
83
|
+
* supervisor's GraphCache rebuild on edits to files the app never reads.
|
|
84
|
+
*/
|
|
85
|
+
(0, vitest_1.it)('does not admit a platformOS-looking path outside the app subtrees', async () => {
|
|
86
|
+
const outside = {
|
|
87
|
+
'tmp/app/views/partials/scratch.liquid': '<div></div>',
|
|
88
|
+
'seed/post_import/app/views/pages/fixture.liquid': '<div></div>',
|
|
89
|
+
'node_modules/pkg/app/lib/helper.liquid': '<div></div>',
|
|
90
|
+
};
|
|
91
|
+
for (const rel of Object.keys(outside))
|
|
92
|
+
(0, vitest_1.expect)((0, index_1.isEdgeSource)(uri(rel), rootUri)).toBe(false);
|
|
93
|
+
// Control: the same three spellings ARE found when they sit at the real root, so
|
|
94
|
+
// the silence above is the anchoring, not the fixture or the walk.
|
|
95
|
+
const files = { ...outside };
|
|
96
|
+
for (const rel of EDGE_SOURCES)
|
|
97
|
+
files[rel] = '<div></div>';
|
|
98
|
+
const fs = new test_1.MockFileSystem(files, rootUri);
|
|
99
|
+
(0, vitest_1.expect)(sorted(await (0, index_1.enumerateEdgeSources)(fs, rootUri))).toEqual(sorted(EDGE_SOURCES.map(uri)));
|
|
100
|
+
});
|
|
101
|
+
(0, vitest_1.it)('never yields a non-platformOS sibling (a bundled react-app/ is skipped)', async () => {
|
|
102
|
+
const fs = makeFs();
|
|
103
|
+
const result = await (0, index_1.enumerateEdgeSources)(fs, rootUri);
|
|
104
|
+
(0, vitest_1.expect)(result).not.toContain(uri('react-app/src/components/Widget.liquid'));
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
/**
|
|
108
|
+
* Every file under `baseUri`, by brute-force recursion into every directory.
|
|
109
|
+
*
|
|
110
|
+
* Deliberately written HERE, and deliberately NOT `walkAppSourceFiles`: that is the walk
|
|
111
|
+
* `enumerateEdgeSources` is built on, so using it for the control too would compare the
|
|
112
|
+
* mechanism against itself and the equivalence assertion above would hold no matter how
|
|
113
|
+
* wrong `APP_SOURCE_SUBTREES` became. An independent walk is the entire value of that test.
|
|
114
|
+
*
|
|
115
|
+
* (It replaces check-common's `recursiveReadDirectory`, which master removed from
|
|
116
|
+
* production once the anchored walk superseded it. Its only remaining purpose was to be
|
|
117
|
+
* this control, and a control belongs next to the test that needs it rather than in a
|
|
118
|
+
* shipped package's public API.)
|
|
119
|
+
*/
|
|
120
|
+
async function everyFileUnder(fs, baseUri) {
|
|
121
|
+
const entries = await fs.readDirectory(baseUri).catch(() => []);
|
|
122
|
+
const nested = await Promise.all(entries.map(async ([uri, type]) => type === platformos_common_1.FileType.Directory ? everyFileUnder(fs, uri) : [uri]));
|
|
123
|
+
return nested.flat();
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=edge-sources.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-sources.spec.js","sourceRoot":"","sources":["../../src/graph/edge-sources.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const platformos_check_common_1 = require("@platformos/platformos-check-common");
|
|
4
|
+
const vitest_1 = require("vitest");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
const toSourceCode_1 = require("../toSourceCode");
|
|
7
|
+
const test_helpers_1 = require("./test-helpers");
|
|
8
|
+
/**
|
|
9
|
+
* `extractFileReferences` is the per-file primitive a `validate_code`-style
|
|
10
|
+
* consumer uses: parse an in-flight buffer with `toSourceCode`, then resolve its
|
|
11
|
+
* outgoing dependency edges against the on-disk project — WITHOUT building the
|
|
12
|
+
* whole app graph. The buffer is never read from disk, so these specs pass the
|
|
13
|
+
* content inline (and even use a `sourceUri` for a file that does not exist).
|
|
14
|
+
*/
|
|
15
|
+
const { fs } = (0, test_helpers_1.getDependencies)();
|
|
16
|
+
/** The exact source range of `snippet` within `source`. */
|
|
17
|
+
function rangeOf(source, snippet) {
|
|
18
|
+
const start = source.indexOf(snippet);
|
|
19
|
+
if (start < 0)
|
|
20
|
+
throw new Error(`snippet not found: ${snippet}`);
|
|
21
|
+
return [start, start + snippet.length];
|
|
22
|
+
}
|
|
23
|
+
function directRef(sourceUri, sourceRange, targetUri, kind, args) {
|
|
24
|
+
return {
|
|
25
|
+
source: { uri: sourceUri, range: sourceRange },
|
|
26
|
+
target: { uri: targetUri },
|
|
27
|
+
type: 'direct',
|
|
28
|
+
kind,
|
|
29
|
+
...(args ? { args } : {}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async function extract(rootUri, sourceUri, content) {
|
|
33
|
+
return (0, index_1.extractFileReferences)(rootUri, sourceUri, await (0, toSourceCode_1.toSourceCode)(sourceUri, content), { fs });
|
|
34
|
+
}
|
|
35
|
+
(0, vitest_1.describe)('extractFileReferences: resolves a single buffer against the project', () => {
|
|
36
|
+
const rootUri = platformos_check_common_1.path.join(test_helpers_1.fixturesRoot, 'function-edges');
|
|
37
|
+
const p = (part) => platformos_check_common_1.path.join(rootUri, ...part.split('/'));
|
|
38
|
+
(0, vitest_1.it)('resolves a {% function %} edge to the canonical lib URI', async () => {
|
|
39
|
+
const sourceUri = p('app/views/pages/draft.liquid'); // not on disk — in-flight buffer
|
|
40
|
+
const content = `{% liquid
|
|
41
|
+
function items = 'queries/list'
|
|
42
|
+
%}`;
|
|
43
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([
|
|
44
|
+
directRef(sourceUri, rangeOf(content, "function items = 'queries/list'"), p('app/lib/queries/list.liquid'), 'function'),
|
|
45
|
+
]);
|
|
46
|
+
});
|
|
47
|
+
(0, vitest_1.it)('resolves a target that does not exist on disk (path-based resolution)', async () => {
|
|
48
|
+
const sourceUri = p('app/views/pages/draft.liquid');
|
|
49
|
+
const content = `{% liquid
|
|
50
|
+
function ghost = 'queries/missing'
|
|
51
|
+
%}`;
|
|
52
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([
|
|
53
|
+
directRef(sourceUri, rangeOf(content, "function ghost = 'queries/missing'"), p('app/lib/queries/missing.liquid'), 'function'),
|
|
54
|
+
]);
|
|
55
|
+
});
|
|
56
|
+
(0, vitest_1.it)('captures the named-argument names at a render call site', async () => {
|
|
57
|
+
const sourceUri = p('app/views/pages/draft.liquid');
|
|
58
|
+
const content = "{% render 'card', title: page.title, count: 3 %}";
|
|
59
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([
|
|
60
|
+
directRef(sourceUri, rangeOf(content, "{% render 'card', title: page.title, count: 3 %}"), p('app/views/partials/card.liquid'), 'render', ['title', 'count']),
|
|
61
|
+
]);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
(0, vitest_1.describe)('extractFileReferences: kinds and resolution match the full graph build', () => {
|
|
65
|
+
(0, vitest_1.it)('tags include edges with kind "include"', async () => {
|
|
66
|
+
const rootUri = platformos_check_common_1.path.join(test_helpers_1.fixturesRoot, 'include-edges');
|
|
67
|
+
const p = (part) => platformos_check_common_1.path.join(rootUri, ...part.split('/'));
|
|
68
|
+
const sourceUri = p('app/views/pages/draft.liquid');
|
|
69
|
+
const content = "{% include 'shared/header' %}";
|
|
70
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([
|
|
71
|
+
directRef(sourceUri, rangeOf(content, "{% include 'shared/header' %}"), p('app/views/partials/shared/header.liquid'), 'include'),
|
|
72
|
+
]);
|
|
73
|
+
});
|
|
74
|
+
(0, vitest_1.it)('resolves a {% graphql %} edge to the .graphql operation file', async () => {
|
|
75
|
+
const rootUri = platformos_check_common_1.path.join(test_helpers_1.fixturesRoot, 'graphql-edges');
|
|
76
|
+
const p = (part) => platformos_check_common_1.path.join(rootUri, ...part.split('/'));
|
|
77
|
+
const sourceUri = p('app/views/pages/draft.liquid');
|
|
78
|
+
const content = `{% liquid
|
|
79
|
+
graphql posts = 'blog_posts/find', id: '1'
|
|
80
|
+
%}`;
|
|
81
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([
|
|
82
|
+
directRef(sourceUri, rangeOf(content, "graphql posts = 'blog_posts/find', id: '1'"), p('app/graphql/blog_posts/find.graphql'), 'graphql', ['id']),
|
|
83
|
+
]);
|
|
84
|
+
});
|
|
85
|
+
(0, vitest_1.it)('resolves module-namespaced render + function targets in declaration order', async () => {
|
|
86
|
+
const rootUri = platformos_check_common_1.path.join(test_helpers_1.fixturesRoot, 'module-edges');
|
|
87
|
+
const p = (part) => platformos_check_common_1.path.join(rootUri, ...part.split('/'));
|
|
88
|
+
const sourceUri = p('app/views/pages/draft.liquid');
|
|
89
|
+
const content = `{% liquid
|
|
90
|
+
function items = 'modules/my_module/queries/get'
|
|
91
|
+
%}
|
|
92
|
+
{% render 'modules/my_module/card' %}`;
|
|
93
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([
|
|
94
|
+
directRef(sourceUri, rangeOf(content, "function items = 'modules/my_module/queries/get'"), p('modules/my_module/public/lib/queries/get.liquid'), 'function'),
|
|
95
|
+
directRef(sourceUri, rangeOf(content, "{% render 'modules/my_module/card' %}"), p('modules/my_module/public/views/partials/card.liquid'), 'render'),
|
|
96
|
+
]);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
(0, vitest_1.describe)('extractFileReferences: only statically resolvable edges', () => {
|
|
100
|
+
const rootUri = platformos_check_common_1.path.join(test_helpers_1.fixturesRoot, 'function-edges');
|
|
101
|
+
const sourceUri = platformos_check_common_1.path.join(rootUri, 'app/views/pages/draft.liquid');
|
|
102
|
+
(0, vitest_1.it)('skips dynamic render targets', async () => {
|
|
103
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, '{% render partial_name %}')).toEqual([]);
|
|
104
|
+
});
|
|
105
|
+
(0, vitest_1.it)('returns nothing for an unparseable buffer instead of throwing', async () => {
|
|
106
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, '{% render %}{% endif %}')).toEqual([]);
|
|
107
|
+
});
|
|
108
|
+
(0, vitest_1.it)('returns nothing for a buffer with no references', async () => {
|
|
109
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, '<h1>{{ page.title }}</h1>')).toEqual([]);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
(0, vitest_1.describe)('extractFileReferences: layout-association edges (frontmatter `layout:`)', () => {
|
|
113
|
+
const rootUri = platformos_check_common_1.path.join(test_helpers_1.fixturesRoot, 'function-edges'); // no layouts here → default path
|
|
114
|
+
const p = (part) => platformos_check_common_1.path.join(rootUri, ...part.split('/'));
|
|
115
|
+
const sourceUri = p('app/views/pages/draft.liquid');
|
|
116
|
+
// The whole frontmatter block: start through the closing `---` line + newline.
|
|
117
|
+
const fmRange = (content) => [
|
|
118
|
+
0,
|
|
119
|
+
content.indexOf('\n', content.indexOf('---', 3)) + 1,
|
|
120
|
+
];
|
|
121
|
+
(0, vitest_1.it)('emits a layout edge for an explicit frontmatter layout', async () => {
|
|
122
|
+
const content = `---
|
|
123
|
+
slug: draft
|
|
124
|
+
layout: theme
|
|
125
|
+
---
|
|
126
|
+
<h1>x</h1>`;
|
|
127
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([
|
|
128
|
+
directRef(sourceUri, fmRange(content), p('app/views/layouts/theme.liquid'), 'layout'),
|
|
129
|
+
]);
|
|
130
|
+
});
|
|
131
|
+
(0, vitest_1.it)('resolves a module-prefixed layout', async () => {
|
|
132
|
+
const content = `---
|
|
133
|
+
layout: modules/core/admin
|
|
134
|
+
---
|
|
135
|
+
<h1>x</h1>`;
|
|
136
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([
|
|
137
|
+
directRef(sourceUri, fmRange(content), p('modules/core/public/views/layouts/admin.liquid'), 'layout'),
|
|
138
|
+
]);
|
|
139
|
+
});
|
|
140
|
+
(0, vitest_1.it)('emits no edge for an explicitly empty layout', async () => {
|
|
141
|
+
const content = `---
|
|
142
|
+
slug: draft
|
|
143
|
+
layout: ''
|
|
144
|
+
---
|
|
145
|
+
<h1>x</h1>`;
|
|
146
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([]);
|
|
147
|
+
});
|
|
148
|
+
(0, vitest_1.it)('emits no edge when layout is omitted (no implicit default)', async () => {
|
|
149
|
+
const content = `---
|
|
150
|
+
slug: draft
|
|
151
|
+
---
|
|
152
|
+
<h1>x</h1>`;
|
|
153
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([]);
|
|
154
|
+
});
|
|
155
|
+
(0, vitest_1.it)('emits no edge for a dynamic layout value', async () => {
|
|
156
|
+
const content = `---
|
|
157
|
+
layout: "{{ context.constants.LAYOUT }}"
|
|
158
|
+
---
|
|
159
|
+
<h1>x</h1>`;
|
|
160
|
+
(0, vitest_1.expect)(await extract(rootUri, sourceUri, content)).toEqual([]);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
//# sourceMappingURL=extract.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.spec.js","sourceRoot":"","sources":["../../src/graph/extract.spec.ts"],"names":[],"mappings":"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"}
|
package/dist/graph/module.d.ts
CHANGED
|
@@ -1,7 +1,75 @@
|
|
|
1
1
|
import { UriString } from '@platformos/platformos-check-common';
|
|
2
|
-
import { AssetModule, AppGraph, AppModule, LiquidModule } from '../types';
|
|
2
|
+
import { AssetModule, AppGraph, AppModule, GraphQLModule, LiquidModule, SchemaModule } from '../types';
|
|
3
3
|
export declare function getModule(appGraph: AppGraph, uri: UriString): AppModule | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Create (or fetch the cached) asset module for an already-resolved URI.
|
|
6
|
+
*
|
|
7
|
+
* Preferred over {@link getAssetModule} whenever the file is known, for the same
|
|
8
|
+
* reason as {@link getPartialModuleByUri}: it does not reconstruct a path from a
|
|
9
|
+
* name, so a nested or module asset keeps the location it actually has.
|
|
10
|
+
*
|
|
11
|
+
* Gated on {@link isSupportedAsset} HERE rather than at each call site, so a new
|
|
12
|
+
* caller cannot forget the gate and mint an Asset node for a value that is not an
|
|
13
|
+
* asset file.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getAssetModuleByUri(appGraph: AppGraph, uri: string): AssetModule | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Whether `nameOrUri` refers to a supported asset file (by extension).
|
|
18
|
+
*
|
|
19
|
+
* The single gate for admitting an asset, whether the subject is a reference (the
|
|
20
|
+
* string inside `{{ 'app.js' | asset_url }}`) or a resolved URI. It preserves the
|
|
21
|
+
* graph's historical behavior of ignoring an `asset_url`-family filter applied to
|
|
22
|
+
* a value that is not an asset file. Exported so the traversal can skip the
|
|
23
|
+
* filesystem probe for a non-asset value BEFORE resolving it; the module
|
|
24
|
+
* factories gate on it again, so neither layer depends on the other remembering.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isSupportedAsset(nameOrUri: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Create (or fetch the cached) asset module for an asset REFERENCE — the string
|
|
29
|
+
* inside `{{ 'app.js' | asset_url }}`, which may carry a `modules/<name>/` prefix.
|
|
30
|
+
*
|
|
31
|
+
* Assets live under the same roots as every other file type: `app/assets/` or
|
|
32
|
+
* `modules/<name>/{public,private}/assets/`. Those come from platformos-common, so the
|
|
33
|
+
* graph resolves a reference to the same place the linter and the platform do.
|
|
34
|
+
*
|
|
35
|
+
* The FIRST candidate is used as the canonical location: this is sync and has no
|
|
36
|
+
* filesystem, so it cannot tell which candidate exists. Prefer
|
|
37
|
+
* {@link getAssetModuleByUri} — the traversal resolves through `DocumentsLocator`,
|
|
38
|
+
* which can.
|
|
39
|
+
*/
|
|
4
40
|
export declare function getAssetModule(appGraph: AppGraph, asset: string): AssetModule | undefined;
|
|
5
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Create (or fetch the cached) Liquid Partial module for an ALREADY-RESOLVED
|
|
43
|
+
* full URI — used for `{% render %}` / `{% include %}` / `{% function %}` /
|
|
44
|
+
* `{% background %}` targets whose URI is resolved canonically by
|
|
45
|
+
* `DocumentsLocator` (which handles lib paths, module prefixes, and extensions).
|
|
46
|
+
* It keys the node by that URI verbatim (normalized), never reconstructing a path
|
|
47
|
+
* from a name: partials have two search roots (`views/partials`, `lib`) and two
|
|
48
|
+
* extensions, so a name-derived path is a guess, and guessing split a `lib/`
|
|
49
|
+
* partial into two nodes. Commands/queries/lib helpers are all `Partial` kind,
|
|
50
|
+
* consistent with check-common's file-type classification.
|
|
51
|
+
*/
|
|
52
|
+
export declare function getPartialModuleByUri(appGraph: AppGraph, uri: string): LiquidModule;
|
|
53
|
+
/**
|
|
54
|
+
* Create (or fetch the cached) GraphQL module for an already-resolved
|
|
55
|
+
* `.graphql` URI — used for `{% graphql op = 'name' %}` targets resolved by
|
|
56
|
+
* `DocumentsLocator`. A leaf node (no outgoing edges).
|
|
57
|
+
*/
|
|
58
|
+
export declare function getGraphQLModuleByUri(appGraph: AppGraph, uri: string): GraphQLModule;
|
|
59
|
+
/**
|
|
60
|
+
* Create (or fetch the cached) Schema module for an already-resolved
|
|
61
|
+
* `custom_model_type`/schema URI — discovered during a full `buildAppGraph`.
|
|
62
|
+
* A leaf node; its `table` (the model `name:`) is populated during traversal.
|
|
63
|
+
*/
|
|
64
|
+
export declare function getSchemaModule(appGraph: AppGraph, uri: string): SchemaModule;
|
|
6
65
|
export declare function getLayoutModule(appGraph: AppGraph, layoutUri: string | false | undefined): LiquidModule | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Create (or fetch the cached) Layout module for an already-resolved layout URI
|
|
68
|
+
* — used for the frontmatter `layout:` association edge, whose target is
|
|
69
|
+
* resolved by `DocumentsLocator` (`'layout'` type: `app/views/layouts`, module
|
|
70
|
+
* prefixes, `.html.liquid`/`.liquid`). Distinct from {@link getLayoutModule} only
|
|
71
|
+
* in that the latter accepts the `string | false | undefined` a frontmatter read
|
|
72
|
+
* yields; both normalize, so both key the same node.
|
|
73
|
+
*/
|
|
74
|
+
export declare function getLayoutModuleByUri(appGraph: AppGraph, uri: string): LiquidModule;
|
|
7
75
|
export declare function getPageModule(appGraph: AppGraph, pageUri: string): LiquidModule;
|
package/dist/graph/module.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getModule = getModule;
|
|
4
|
+
exports.getAssetModuleByUri = getAssetModuleByUri;
|
|
5
|
+
exports.isSupportedAsset = isSupportedAsset;
|
|
4
6
|
exports.getAssetModule = getAssetModule;
|
|
5
|
-
exports.
|
|
7
|
+
exports.getPartialModuleByUri = getPartialModuleByUri;
|
|
8
|
+
exports.getGraphQLModuleByUri = getGraphQLModuleByUri;
|
|
9
|
+
exports.getSchemaModule = getSchemaModule;
|
|
6
10
|
exports.getLayoutModule = getLayoutModule;
|
|
11
|
+
exports.getLayoutModuleByUri = getLayoutModuleByUri;
|
|
7
12
|
exports.getPageModule = getPageModule;
|
|
8
13
|
const platformos_check_common_1 = require("@platformos/platformos-check-common");
|
|
14
|
+
const platformos_common_1 = require("@platformos/platformos-common");
|
|
9
15
|
const types_1 = require("../types");
|
|
10
16
|
const utils_1 = require("../utils");
|
|
11
17
|
/**
|
|
@@ -28,48 +34,153 @@ function getModule(appGraph, uri) {
|
|
|
28
34
|
if (cache.has(uri)) {
|
|
29
35
|
return cache.get(uri);
|
|
30
36
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
// One anchored classification, not four unanchored ones: a file's type is its
|
|
38
|
+
// position relative to the project root, and the graph has that root.
|
|
39
|
+
switch ((0, platformos_common_1.getFileType)(uri, appGraph.rootUri)) {
|
|
40
|
+
case platformos_common_1.PlatformOSFileType.Layout:
|
|
34
41
|
return getLayoutModule(appGraph, uri);
|
|
35
|
-
case
|
|
42
|
+
case platformos_common_1.PlatformOSFileType.Page:
|
|
36
43
|
return getPageModule(appGraph, uri);
|
|
37
|
-
case
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
case platformos_common_1.PlatformOSFileType.Partial:
|
|
45
|
+
// The URI is already resolved, so it is used as-is. Reducing it to a
|
|
46
|
+
// `basename` and rebuilding a path from that loses any subdirectory and any
|
|
47
|
+
// module prefix — `app/views/partials/ui/card.liquid` came back as
|
|
48
|
+
// `app/views/partials/card.liquid`, a node for a file that need not exist,
|
|
49
|
+
// and `app/lib/can/x.liquid` was split from the same file resolved as an
|
|
50
|
+
// edge target (which comes through getPartialModuleByUri).
|
|
51
|
+
return getPartialModuleByUri(appGraph, uri);
|
|
52
|
+
case platformos_common_1.PlatformOSFileType.Asset:
|
|
53
|
+
return getAssetModuleByUri(appGraph, uri);
|
|
41
54
|
}
|
|
42
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Create (or fetch the cached) asset module for an already-resolved URI.
|
|
58
|
+
*
|
|
59
|
+
* Preferred over {@link getAssetModule} whenever the file is known, for the same
|
|
60
|
+
* reason as {@link getPartialModuleByUri}: it does not reconstruct a path from a
|
|
61
|
+
* name, so a nested or module asset keeps the location it actually has.
|
|
62
|
+
*
|
|
63
|
+
* Gated on {@link isSupportedAsset} HERE rather than at each call site, so a new
|
|
64
|
+
* caller cannot forget the gate and mint an Asset node for a value that is not an
|
|
65
|
+
* asset file.
|
|
66
|
+
*/
|
|
67
|
+
function getAssetModuleByUri(appGraph, uri) {
|
|
68
|
+
if (!isSupportedAsset(uri))
|
|
69
|
+
return undefined;
|
|
70
|
+
return module(appGraph, {
|
|
71
|
+
type: "Asset" /* ModuleType.Asset */,
|
|
72
|
+
kind: 'unused',
|
|
73
|
+
// Normalize to forward slashes — see getPartialModuleByUri.
|
|
74
|
+
uri: platformos_check_common_1.path.normalize(uri),
|
|
75
|
+
dependencies: [],
|
|
76
|
+
references: [],
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/** File extensions the graph treats as assets (the `asset_url` edge gate). */
|
|
80
|
+
const SUPPORTED_ASSET_EXTENSIONS = [
|
|
81
|
+
...types_1.SUPPORTED_ASSET_IMAGE_EXTENSIONS,
|
|
82
|
+
'js',
|
|
83
|
+
'css',
|
|
84
|
+
'svg',
|
|
85
|
+
'pdf',
|
|
86
|
+
'woff',
|
|
87
|
+
'woff2',
|
|
88
|
+
'ttf',
|
|
89
|
+
'eot',
|
|
90
|
+
];
|
|
91
|
+
/**
|
|
92
|
+
* Whether `nameOrUri` refers to a supported asset file (by extension).
|
|
93
|
+
*
|
|
94
|
+
* The single gate for admitting an asset, whether the subject is a reference (the
|
|
95
|
+
* string inside `{{ 'app.js' | asset_url }}`) or a resolved URI. It preserves the
|
|
96
|
+
* graph's historical behavior of ignoring an `asset_url`-family filter applied to
|
|
97
|
+
* a value that is not an asset file. Exported so the traversal can skip the
|
|
98
|
+
* filesystem probe for a non-asset value BEFORE resolving it; the module
|
|
99
|
+
* factories gate on it again, so neither layer depends on the other remembering.
|
|
100
|
+
*/
|
|
101
|
+
function isSupportedAsset(nameOrUri) {
|
|
102
|
+
return SUPPORTED_ASSET_EXTENSIONS.includes((0, utils_1.extname)(nameOrUri));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create (or fetch the cached) asset module for an asset REFERENCE — the string
|
|
106
|
+
* inside `{{ 'app.js' | asset_url }}`, which may carry a `modules/<name>/` prefix.
|
|
107
|
+
*
|
|
108
|
+
* Assets live under the same roots as every other file type: `app/assets/` or
|
|
109
|
+
* `modules/<name>/{public,private}/assets/`. Those come from platformos-common, so the
|
|
110
|
+
* graph resolves a reference to the same place the linter and the platform do.
|
|
111
|
+
*
|
|
112
|
+
* The FIRST candidate is used as the canonical location: this is sync and has no
|
|
113
|
+
* filesystem, so it cannot tell which candidate exists. Prefer
|
|
114
|
+
* {@link getAssetModuleByUri} — the traversal resolves through `DocumentsLocator`,
|
|
115
|
+
* which can.
|
|
116
|
+
*/
|
|
43
117
|
function getAssetModule(appGraph, asset) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
'css',
|
|
49
|
-
'svg',
|
|
50
|
-
'pdf',
|
|
51
|
-
'woff',
|
|
52
|
-
'woff2',
|
|
53
|
-
'ttf',
|
|
54
|
-
'eot',
|
|
55
|
-
];
|
|
56
|
-
if (!SUPPORTED_ASSET_EXTENSIONS.includes(extension)) {
|
|
118
|
+
if (!isSupportedAsset(asset))
|
|
119
|
+
return undefined;
|
|
120
|
+
const [canonical] = (0, platformos_common_1.nameToPaths)(platformos_common_1.PlatformOSFileType.Asset, asset);
|
|
121
|
+
if (!canonical)
|
|
57
122
|
return undefined;
|
|
58
|
-
}
|
|
59
123
|
return module(appGraph, {
|
|
60
124
|
type: "Asset" /* ModuleType.Asset */,
|
|
61
125
|
kind: 'unused',
|
|
126
|
+
uri: platformos_check_common_1.path.join(appGraph.rootUri, canonical),
|
|
62
127
|
dependencies: [],
|
|
63
128
|
references: [],
|
|
64
|
-
uri: platformos_check_common_1.path.join(appGraph.rootUri, 'assets', asset),
|
|
65
129
|
});
|
|
66
130
|
}
|
|
67
|
-
|
|
68
|
-
|
|
131
|
+
/**
|
|
132
|
+
* Create (or fetch the cached) Liquid Partial module for an ALREADY-RESOLVED
|
|
133
|
+
* full URI — used for `{% render %}` / `{% include %}` / `{% function %}` /
|
|
134
|
+
* `{% background %}` targets whose URI is resolved canonically by
|
|
135
|
+
* `DocumentsLocator` (which handles lib paths, module prefixes, and extensions).
|
|
136
|
+
* It keys the node by that URI verbatim (normalized), never reconstructing a path
|
|
137
|
+
* from a name: partials have two search roots (`views/partials`, `lib`) and two
|
|
138
|
+
* extensions, so a name-derived path is a guess, and guessing split a `lib/`
|
|
139
|
+
* partial into two nodes. Commands/queries/lib helpers are all `Partial` kind,
|
|
140
|
+
* consistent with check-common's file-type classification.
|
|
141
|
+
*/
|
|
142
|
+
function getPartialModuleByUri(appGraph, uri) {
|
|
69
143
|
return module(appGraph, {
|
|
70
144
|
type: "Liquid" /* ModuleType.Liquid */,
|
|
71
145
|
kind: "partial" /* LiquidModuleKind.Partial */,
|
|
72
|
-
|
|
146
|
+
// Normalize to forward slashes so module keys match the rest of the graph
|
|
147
|
+
// (getAssetModule builds its URI via path.join, which normalizes).
|
|
148
|
+
// DocumentsLocator returns `Utils.joinPath(...).toString()` unnormalized,
|
|
149
|
+
// which on Windows keeps backslashes and breaks key/edge matching against the
|
|
150
|
+
// normalized URIs everywhere else.
|
|
151
|
+
uri: platformos_check_common_1.path.normalize(uri),
|
|
152
|
+
dependencies: [],
|
|
153
|
+
references: [],
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Create (or fetch the cached) GraphQL module for an already-resolved
|
|
158
|
+
* `.graphql` URI — used for `{% graphql op = 'name' %}` targets resolved by
|
|
159
|
+
* `DocumentsLocator`. A leaf node (no outgoing edges).
|
|
160
|
+
*/
|
|
161
|
+
function getGraphQLModuleByUri(appGraph, uri) {
|
|
162
|
+
return module(appGraph, {
|
|
163
|
+
type: "GraphQL" /* ModuleType.GraphQL */,
|
|
164
|
+
kind: 'graphql',
|
|
165
|
+
// Normalize to forward slashes — see getPartialModuleByUri.
|
|
166
|
+
uri: platformos_check_common_1.path.normalize(uri),
|
|
167
|
+
dependencies: [],
|
|
168
|
+
references: [],
|
|
169
|
+
// Always present (empty = no table declared); populated during traversal.
|
|
170
|
+
tables: [],
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Create (or fetch the cached) Schema module for an already-resolved
|
|
175
|
+
* `custom_model_type`/schema URI — discovered during a full `buildAppGraph`.
|
|
176
|
+
* A leaf node; its `table` (the model `name:`) is populated during traversal.
|
|
177
|
+
*/
|
|
178
|
+
function getSchemaModule(appGraph, uri) {
|
|
179
|
+
return module(appGraph, {
|
|
180
|
+
type: "Schema" /* ModuleType.Schema */,
|
|
181
|
+
kind: 'schema',
|
|
182
|
+
// Normalize to forward slashes — see getPartialModuleByUri.
|
|
183
|
+
uri: platformos_check_common_1.path.normalize(uri),
|
|
73
184
|
dependencies: [],
|
|
74
185
|
references: [],
|
|
75
186
|
});
|
|
@@ -80,7 +191,29 @@ function getLayoutModule(appGraph, layoutUri) {
|
|
|
80
191
|
return module(appGraph, {
|
|
81
192
|
type: "Liquid" /* ModuleType.Liquid */,
|
|
82
193
|
kind: "layout" /* LiquidModuleKind.Layout */,
|
|
83
|
-
|
|
194
|
+
// Normalize so a layout discovered as an entry point keys identically to the
|
|
195
|
+
// same file resolved as a frontmatter `layout:` edge target (which comes
|
|
196
|
+
// through getLayoutModuleByUri, also normalized) — one node, never a split
|
|
197
|
+
// identity. See getPartialModuleByUri for why DocumentsLocator/fs URIs must
|
|
198
|
+
// be normalized.
|
|
199
|
+
uri: platformos_check_common_1.path.normalize(layoutUri),
|
|
200
|
+
dependencies: [],
|
|
201
|
+
references: [],
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Create (or fetch the cached) Layout module for an already-resolved layout URI
|
|
206
|
+
* — used for the frontmatter `layout:` association edge, whose target is
|
|
207
|
+
* resolved by `DocumentsLocator` (`'layout'` type: `app/views/layouts`, module
|
|
208
|
+
* prefixes, `.html.liquid`/`.liquid`). Distinct from {@link getLayoutModule} only
|
|
209
|
+
* in that the latter accepts the `string | false | undefined` a frontmatter read
|
|
210
|
+
* yields; both normalize, so both key the same node.
|
|
211
|
+
*/
|
|
212
|
+
function getLayoutModuleByUri(appGraph, uri) {
|
|
213
|
+
return module(appGraph, {
|
|
214
|
+
type: "Liquid" /* ModuleType.Liquid */,
|
|
215
|
+
kind: "layout" /* LiquidModuleKind.Layout */,
|
|
216
|
+
uri: platformos_check_common_1.path.normalize(uri),
|
|
84
217
|
dependencies: [],
|
|
85
218
|
references: [],
|
|
86
219
|
});
|
|
@@ -89,7 +222,9 @@ function getPageModule(appGraph, pageUri) {
|
|
|
89
222
|
return module(appGraph, {
|
|
90
223
|
type: "Liquid" /* ModuleType.Liquid */,
|
|
91
224
|
kind: "page" /* LiquidModuleKind.Page */,
|
|
92
|
-
|
|
225
|
+
// Normalize for the same node-identity reason as getLayoutModule / the other
|
|
226
|
+
// factories (see getPartialModuleByUri).
|
|
227
|
+
uri: platformos_check_common_1.path.normalize(pageUri),
|
|
93
228
|
dependencies: [],
|
|
94
229
|
references: [],
|
|
95
230
|
});
|