@platformos/platformos-graph 0.0.20 → 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 +511 -8
- 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.js +18 -13
- package/dist/cli.js.map +1 -1
- 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 -0
- 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 +60 -7
- package/dist/graph/module.js +137 -41
- 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.js +3 -3
- 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 +51 -20
- package/dist/graph/traverse.js +239 -29
- package/dist/graph/traverse.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +19 -1
- 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 +102 -3
- 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/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/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/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/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 +37 -31
- package/src/cli.ts +31 -15
- package/src/graph/augment.ts +4 -0
- package/src/graph/build.spec.ts +871 -6
- 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 +139 -45
- 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 +3 -3
- package/src/graph/{extract.spec.ts → traverse.spec.ts} +125 -2
- package/src/graph/traverse.ts +278 -37
- 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 +106 -7
- package/src/utils/index.ts +1 -1
- package/dist/getWebComponentMap.d.ts +0 -10
- package/dist/getWebComponentMap.js +0 -66
- package/dist/getWebComponentMap.js.map +0 -1
- package/src/graph/traverse-edges.spec.ts +0 -278
- /package/fixtures/skeleton/{assets → app/assets}/app.css +0 -0
- /package/fixtures/skeleton/{assets → app/assets}/app.js +0 -0
package/dist/graph/build.d.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
import { UriString } from '@platformos/platformos-check-common';
|
|
2
|
-
import { IDependencies, AppGraph } from '../types';
|
|
3
|
-
|
|
2
|
+
import { IDependencies, AppGraph, GraphBuildOptions } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Build the project dependency graph.
|
|
5
|
+
*
|
|
6
|
+
* - `entryPoints` omitted → FULL build: a single directory sweep discovers pages
|
|
7
|
+
* + layouts (the render entry points) and standalone custom-model-type/schema
|
|
8
|
+
* nodes, and every reachable module is materialized.
|
|
9
|
+
* - `entryPoints` provided → SCOPED build (e.g. an LSP rebuild for changed
|
|
10
|
+
* files): built verbatim from those roots. Schema nodes are NOT auto-discovered
|
|
11
|
+
* in this mode — schema discovery is a full-build concern.
|
|
12
|
+
*
|
|
13
|
+
* `options.includeStructural` (default off) additionally populates each
|
|
14
|
+
* `LiquidModule.structural`; see {@link GraphBuildOptions}.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildAppGraph(rootUri: UriString, ideps: IDependencies, entryPoints?: UriString[], options?: GraphBuildOptions): Promise<AppGraph>;
|
package/dist/graph/build.js
CHANGED
|
@@ -1,21 +1,60 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildAppGraph = buildAppGraph;
|
|
4
|
-
const
|
|
4
|
+
const platformos_common_1 = require("@platformos/platformos-common");
|
|
5
5
|
const augment_1 = require("./augment");
|
|
6
6
|
const module_1 = require("./module");
|
|
7
7
|
const traverse_1 = require("./traverse");
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Build the project dependency graph.
|
|
10
|
+
*
|
|
11
|
+
* - `entryPoints` omitted → FULL build: a single directory sweep discovers pages
|
|
12
|
+
* + layouts (the render entry points) and standalone custom-model-type/schema
|
|
13
|
+
* nodes, and every reachable module is materialized.
|
|
14
|
+
* - `entryPoints` provided → SCOPED build (e.g. an LSP rebuild for changed
|
|
15
|
+
* files): built verbatim from those roots. Schema nodes are NOT auto-discovered
|
|
16
|
+
* in this mode — schema discovery is a full-build concern.
|
|
17
|
+
*
|
|
18
|
+
* `options.includeStructural` (default off) additionally populates each
|
|
19
|
+
* `LiquidModule.structural`; see {@link GraphBuildOptions}.
|
|
20
|
+
*/
|
|
21
|
+
async function buildAppGraph(rootUri, ideps, entryPoints, options = {}) {
|
|
9
22
|
const deps = (0, augment_1.augmentDependencies)(rootUri, ideps);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
// Table (schema / custom-model-type) files are platform nodes but are NOT
|
|
24
|
+
// render-reachable — nothing renders them — so they never appear via edge traversal. On
|
|
25
|
+
// a full build they are discovered as standalone leaf nodes, never entry points, so
|
|
26
|
+
// reachability/orphan semantics for the render graph are unaffected.
|
|
27
|
+
let schemaUris = [];
|
|
28
|
+
// An explicit entryPoints scope is built verbatim (e.g. a scoped LSP rebuild); the
|
|
29
|
+
// default full build (`entryPoints === undefined`) also discovers standalone Table
|
|
30
|
+
// nodes. Branching on the parameter directly lets the compiler narrow it below.
|
|
31
|
+
if (entryPoints === undefined) {
|
|
32
|
+
// ONE sweep yields both populations, partitioned by SourceCodeType below, so the
|
|
33
|
+
// tree is walked once. `walkAppSourceFiles` is anchored on APP_SOURCE_SUBTREES: the
|
|
34
|
+
// walk it replaces started at the root and skipped directories by NAME, which both
|
|
35
|
+
// dropped `app/views/pages/vendor/**` (a live site section — 137 files on one real
|
|
36
|
+
// project) and admitted `tmp/app/views/partials/x.liquid`.
|
|
37
|
+
const discovered = await (0, platformos_common_1.walkAppSourceFiles)(deps.fs, rootUri, ([uri]) => {
|
|
38
|
+
// Root-ANCHORED classification. The unanchored `getFileType(uri)` this used to call
|
|
39
|
+
// matched a known directory anywhere in the path, so
|
|
40
|
+
// `seed/post_import/app/migrations/x.liquid` classified as a Migration while being
|
|
41
|
+
// correctly absent from the lint's app.
|
|
42
|
+
const fileType = (0, platformos_common_1.getFileType)(uri, rootUri);
|
|
43
|
+
// A GRAPH-domain restriction, not a second answer to "what is a source file":
|
|
44
|
+
// Liquid is the only source that can reference another file, so a non-Liquid entry
|
|
45
|
+
// point would have no edges to traverse. Which extensions ARE Liquid still comes
|
|
46
|
+
// from platformos-common, never spelled here — which is also why the `.yml`/`.yaml`
|
|
47
|
+
// tests that used to partition this sweep are gone: `.yaml` is not a platformOS
|
|
48
|
+
// extension at all, so spelling it here promised coverage the platform never had.
|
|
49
|
+
if ((0, platformos_common_1.sourceCodeTypeOf)(uri) === platformos_common_1.SourceCodeType.LiquidHtml) {
|
|
50
|
+
// Layouts wrap all page content; pages are directly requested — both are entry points.
|
|
51
|
+
return fileType === platformos_common_1.PlatformOSFileType.Layout || fileType === platformos_common_1.PlatformOSFileType.Page;
|
|
52
|
+
}
|
|
53
|
+
return fileType === platformos_common_1.PlatformOSFileType.Table;
|
|
54
|
+
});
|
|
55
|
+
entryPoints = discovered.filter((uri) => (0, platformos_common_1.sourceCodeTypeOf)(uri) === platformos_common_1.SourceCodeType.LiquidHtml);
|
|
56
|
+
schemaUris = discovered.filter((uri) => (0, platformos_common_1.sourceCodeTypeOf)(uri) !== platformos_common_1.SourceCodeType.LiquidHtml);
|
|
57
|
+
}
|
|
19
58
|
const graph = {
|
|
20
59
|
entryPoints: [],
|
|
21
60
|
modules: {},
|
|
@@ -24,7 +63,10 @@ async function buildAppGraph(rootUri, ideps, entryPoints) {
|
|
|
24
63
|
graph.entryPoints = entryPoints
|
|
25
64
|
.map((uri) => (0, module_1.getModule)(graph, uri))
|
|
26
65
|
.filter((x) => x !== undefined);
|
|
27
|
-
await Promise.all(graph.entryPoints.map((entry) => (0, traverse_1.traverseModule)(entry, graph, deps)));
|
|
66
|
+
await Promise.all(graph.entryPoints.map((entry) => (0, traverse_1.traverseModule)(entry, graph, deps, options)));
|
|
67
|
+
if (schemaUris.length > 0) {
|
|
68
|
+
await Promise.all(schemaUris.map((uri) => (0, traverse_1.traverseModule)((0, module_1.getSchemaModule)(graph, uri), graph, deps, options)));
|
|
69
|
+
}
|
|
28
70
|
return graph;
|
|
29
71
|
}
|
|
30
72
|
//# sourceMappingURL=build.js.map
|
package/dist/graph/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/graph/build.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/graph/build.ts"],"names":[],"mappings":";;AA0BA,sCAkEC;AA3FD,qEAMuC;AAEvC,uCAAgD;AAChD,qCAAsD;AACtD,yCAA4C;AAE5C;;;;;;;;;;;;GAYG;AACI,KAAK,UAAU,aAAa,CACjC,OAAkB,EAClB,KAAoB,EACpB,WAAyB,EACzB,UAA6B,EAAE;IAE/B,MAAM,IAAI,GAAG,IAAA,6BAAmB,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAEjD,0EAA0E;IAC1E,wFAAwF;IACxF,oFAAoF;IACpF,qEAAqE;IACrE,IAAI,UAAU,GAAgB,EAAE,CAAC;IAEjC,mFAAmF;IACnF,mFAAmF;IACnF,gFAAgF;IAChF,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,iFAAiF;QACjF,oFAAoF;QACpF,mFAAmF;QACnF,mFAAmF;QACnF,2DAA2D;QAC3D,MAAM,UAAU,GAAG,MAAM,IAAA,sCAAkB,EAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE;YACtE,oFAAoF;YACpF,qDAAqD;YACrD,mFAAmF;YACnF,wCAAwC;YACxC,MAAM,QAAQ,GAAG,IAAA,+BAAW,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAE3C,8EAA8E;YAC9E,mFAAmF;YACnF,iFAAiF;YACjF,oFAAoF;YACpF,gFAAgF;YAChF,kFAAkF;YAClF,IAAI,IAAA,oCAAgB,EAAC,GAAG,CAAC,KAAK,kCAAc,CAAC,UAAU,EAAE,CAAC;gBACxD,uFAAuF;gBACvF,OAAO,QAAQ,KAAK,sCAAkB,CAAC,MAAM,IAAI,QAAQ,KAAK,sCAAkB,CAAC,IAAI,CAAC;YACxF,CAAC;YACD,OAAO,QAAQ,KAAK,sCAAkB,CAAC,KAAK,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,oCAAgB,EAAC,GAAG,CAAC,KAAK,kCAAc,CAAC,UAAU,CAAC,CAAC;QAC9F,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,oCAAgB,EAAC,GAAG,CAAC,KAAK,kCAAc,CAAC,UAAU,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,KAAK,GAAa;QACtB,WAAW,EAAE,EAAE;QACf,OAAO,EAAE,EAAE;QACX,OAAO;KACR,CAAC;IAEF,KAAK,CAAC,WAAW,GAAG,WAAW;SAC5B,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,kBAAS,EAAC,KAAK,EAAE,GAAG,CAAC,CAAC;SACnC,MAAM,CAAC,CAAC,CAAC,EAAkB,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IAElD,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,yBAAc,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAEjG,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,OAAO,CAAC,GAAG,CACf,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,yBAAc,EAAC,IAAA,wBAAe,EAAC,KAAK,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAC3F,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const platformos_check_common_1 = require("@platformos/platformos-check-common");
|
|
4
|
+
const test_1 = require("@platformos/platformos-check-common/src/test");
|
|
5
|
+
const vitest_1 = require("vitest");
|
|
6
|
+
const index_1 = require("../index");
|
|
7
|
+
const toSourceCode_1 = require("../toSourceCode");
|
|
8
|
+
const test_helpers_1 = require("./test-helpers");
|
|
9
|
+
(0, vitest_1.describe)('Module: index', () => {
|
|
10
|
+
const rootUri = test_helpers_1.skeleton;
|
|
11
|
+
const p = (part) => platformos_check_common_1.path.join(rootUri, ...part.split('/'));
|
|
12
|
+
const loc = (part) => vitest_1.expect.objectContaining({ uri: p(part) });
|
|
13
|
+
let dependencies;
|
|
14
|
+
(0, vitest_1.beforeAll)(async () => {
|
|
15
|
+
dependencies = (0, test_helpers_1.getDependencies)();
|
|
16
|
+
}, 15000);
|
|
17
|
+
(0, vitest_1.describe)('Unit: buildAppGraph', { timeout: 10000 }, () => {
|
|
18
|
+
(0, vitest_1.it)('builds a graph of the app', { timeout: 10000 }, async () => {
|
|
19
|
+
const graph = await (0, index_1.buildAppGraph)(rootUri, dependencies);
|
|
20
|
+
(0, vitest_1.expect)(graph).toBeDefined();
|
|
21
|
+
});
|
|
22
|
+
(0, vitest_1.describe)('with a valid app graph', () => {
|
|
23
|
+
let graph;
|
|
24
|
+
(0, vitest_1.beforeEach)(async () => {
|
|
25
|
+
graph = await (0, index_1.buildAppGraph)(rootUri, dependencies);
|
|
26
|
+
});
|
|
27
|
+
(0, vitest_1.it)('has a root URI', () => {
|
|
28
|
+
(0, vitest_1.expect)(graph.rootUri).toBeDefined();
|
|
29
|
+
(0, vitest_1.expect)(graph.rootUri).toBe(rootUri);
|
|
30
|
+
});
|
|
31
|
+
(0, vitest_1.it)('infers entry points from layouts and pages', () => {
|
|
32
|
+
(0, vitest_1.expect)(graph.entryPoints).toHaveLength(2);
|
|
33
|
+
(0, vitest_1.expect)(graph.entryPoints.map((x) => x.uri)).toEqual(vitest_1.expect.arrayContaining([
|
|
34
|
+
p('app/views/layouts/application.liquid'),
|
|
35
|
+
p('app/views/pages/index.liquid'),
|
|
36
|
+
]));
|
|
37
|
+
});
|
|
38
|
+
(0, vitest_1.it)("finds app/views/layouts/application.liquid's dependencies", () => {
|
|
39
|
+
const layout = graph.modules[p('app/views/layouts/application.liquid')];
|
|
40
|
+
(0, vitest_1.assert)(layout);
|
|
41
|
+
(0, vitest_1.assert)(layout.type === "Liquid" /* ModuleType.Liquid */);
|
|
42
|
+
(0, vitest_1.assert)(layout.kind === "layout" /* LiquidModuleKind.Layout */);
|
|
43
|
+
const deps = layout.dependencies;
|
|
44
|
+
(0, vitest_1.expect)(deps.map((x) => x.target.uri)).toEqual(vitest_1.expect.arrayContaining([
|
|
45
|
+
p('app/assets/app.js'),
|
|
46
|
+
p('app/assets/app.css'),
|
|
47
|
+
p('app/views/partials/header.liquid'),
|
|
48
|
+
]));
|
|
49
|
+
});
|
|
50
|
+
(0, vitest_1.it)("finds app/views/partials/parent's dependencies and references", async () => {
|
|
51
|
+
const parentPartial = graph.modules[p('app/views/partials/parent.liquid')];
|
|
52
|
+
(0, vitest_1.assert)(parentPartial);
|
|
53
|
+
(0, vitest_1.assert)(parentPartial.type === "Liquid" /* ModuleType.Liquid */);
|
|
54
|
+
(0, vitest_1.assert)(parentPartial.kind === "partial" /* LiquidModuleKind.Partial */);
|
|
55
|
+
// outgoing links — parent renders exactly one partial (child)
|
|
56
|
+
const deps = parentPartial.dependencies;
|
|
57
|
+
(0, vitest_1.assert)(deps.map((x) => x.source.uri).every((x) => x === parentPartial.uri));
|
|
58
|
+
(0, vitest_1.expect)(deps.map((x) => x.target.uri)).toEqual([p('app/views/partials/child.liquid')]);
|
|
59
|
+
// {% render 'child' %} dependency
|
|
60
|
+
const parentSource = await dependencies.getSourceCode(p('app/views/partials/parent.liquid'));
|
|
61
|
+
(0, vitest_1.assert)(parentSource);
|
|
62
|
+
(0, vitest_1.assert)(parentSource.type === platformos_check_common_1.SourceCodeType.LiquidHtml);
|
|
63
|
+
(0, vitest_1.expect)(parentPartial.dependencies.map((x) => x.source)).toContainEqual(vitest_1.expect.objectContaining({
|
|
64
|
+
uri: p('app/views/partials/parent.liquid'),
|
|
65
|
+
range: [
|
|
66
|
+
parentSource.source.indexOf('{% render "child"'),
|
|
67
|
+
parentSource.source.indexOf('{% render "child"') +
|
|
68
|
+
'{% render "child", children: children %}'.length,
|
|
69
|
+
],
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
(0, vitest_1.it)("finds app/views/partials/child's references", () => {
|
|
73
|
+
const childPartial = graph.modules[p('app/views/partials/child.liquid')];
|
|
74
|
+
(0, vitest_1.assert)(childPartial);
|
|
75
|
+
(0, vitest_1.assert)(childPartial.type === "Liquid" /* ModuleType.Liquid */);
|
|
76
|
+
(0, vitest_1.assert)(childPartial.kind === "partial" /* LiquidModuleKind.Partial */);
|
|
77
|
+
const refs = childPartial.references;
|
|
78
|
+
(0, vitest_1.expect)(refs.map((x) => x.source.uri)).toEqual(vitest_1.expect.arrayContaining([
|
|
79
|
+
p('app/views/partials/parent.liquid'),
|
|
80
|
+
p('app/views/partials/header.liquid'),
|
|
81
|
+
]));
|
|
82
|
+
});
|
|
83
|
+
(0, vitest_1.it)('tags every layout edge with its kind (asset, asset, render)', () => {
|
|
84
|
+
const layout = graph.modules[p('app/views/layouts/application.liquid')];
|
|
85
|
+
(0, vitest_1.assert)(layout);
|
|
86
|
+
// The complete, ordered edge set — not a membership probe — so an extra,
|
|
87
|
+
// missing, or mis-kinded edge fails. (Source ranges are pinned by the
|
|
88
|
+
// dedicated render-dependency test above.)
|
|
89
|
+
(0, vitest_1.expect)(layout.dependencies.map((d) => ({ target: d.target.uri, type: d.type, kind: d.kind }))).toEqual([
|
|
90
|
+
{ target: p('app/assets/app.js'), type: 'direct', kind: 'asset' },
|
|
91
|
+
{ target: p('app/assets/app.css'), type: 'direct', kind: 'asset' },
|
|
92
|
+
{ target: p('app/views/partials/header.liquid'), type: 'direct', kind: 'render' },
|
|
93
|
+
]);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
/**
|
|
97
|
+
* Entry points come from an ANCHORED walk of the app subtrees, so what a
|
|
98
|
+
* directory is CALLED never decides whether the graph can see it. The walk this
|
|
99
|
+
* replaced skipped any directory ending in `vendor`, `build`, `tmp` or `dist`,
|
|
100
|
+
* which lost every page under `app/views/pages/vendor/**` — a real section of a
|
|
101
|
+
* real site — while still descending into `tmp/app/views/pages/`, which the
|
|
102
|
+
* platform does not deploy at all.
|
|
103
|
+
*/
|
|
104
|
+
(0, vitest_1.describe)('entry points on a project with app directories named like build output', () => {
|
|
105
|
+
const projectRoot = 'file:///project';
|
|
106
|
+
const u = (part) => `${projectRoot}/${part}`;
|
|
107
|
+
let graph;
|
|
108
|
+
(0, vitest_1.beforeEach)(async () => {
|
|
109
|
+
const fs = new test_1.MockFileSystem({
|
|
110
|
+
'app/views/pages/vendor/index.liquid': `{% render 'vendor/card' %}`,
|
|
111
|
+
'app/views/pages/build/status.liquid': `ok`,
|
|
112
|
+
'app/views/partials/vendor/card.liquid': `a card`,
|
|
113
|
+
'tmp/app/views/pages/scratch.liquid': `not deployed`,
|
|
114
|
+
'node_modules/some-pkg/app/views/pages/decoy.liquid': `not ours`,
|
|
115
|
+
'dist/app/views/pages/bundled.liquid': `build output`,
|
|
116
|
+
}, projectRoot);
|
|
117
|
+
graph = await (0, index_1.buildAppGraph)(projectRoot, {
|
|
118
|
+
fs,
|
|
119
|
+
getSourceCode: async (uri) => (0, toSourceCode_1.toSourceCode)(uri, await fs.readFile(uri)),
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
(0, vitest_1.it)('finds the pages under vendor/ and build/, and nothing outside the app subtrees', () => {
|
|
123
|
+
(0, vitest_1.expect)(graph.entryPoints.map((entry) => entry.uri).sort()).toEqual([
|
|
124
|
+
u('app/views/pages/build/status.liquid'),
|
|
125
|
+
u('app/views/pages/vendor/index.liquid'),
|
|
126
|
+
]);
|
|
127
|
+
});
|
|
128
|
+
(0, vitest_1.it)('traverses them, so a partial under vendor/ is a graph node with a reference', () => {
|
|
129
|
+
const card = graph.modules[u('app/views/partials/vendor/card.liquid')];
|
|
130
|
+
(0, vitest_1.assert)(card);
|
|
131
|
+
(0, vitest_1.expect)(card.references.map((reference) => reference.source.uri)).toEqual([
|
|
132
|
+
u('app/views/pages/vendor/index.liquid'),
|
|
133
|
+
]);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=build.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.spec.js","sourceRoot":"","sources":["../../src/graph/build.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type UriString } from '@platformos/platformos-check-common';
|
|
2
|
+
import { type AbstractFileSystem } from '@platformos/platformos-common';
|
|
3
|
+
/**
|
|
4
|
+
* The canonical definition of an EDGE SOURCE: a liquid file whose own content can declare
|
|
5
|
+
* outgoing edges (a Page, Layout, or Partial). Only these files' add/remove/modify can change
|
|
6
|
+
* any file's set of dependents — `.graphql`/`.yml`/asset files are leaves.
|
|
7
|
+
*
|
|
8
|
+
* "Which files" derives entirely from the file-type classifier, so this predicate never
|
|
9
|
+
* re-encodes the classification. It is ANCHORED on `rootUri`, because a file's type IS its
|
|
10
|
+
* position relative to the project root: unanchored, `tmp/app/lib/x.liquid` is a Partial.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isEdgeSource(uri: UriString, rootUri: UriString): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Enumerate every edge-source liquid file under a project root — the single canonical primitive
|
|
15
|
+
* for "which files are the graph's edge sources". Consumers never re-derive the walk or the
|
|
16
|
+
* {@link isEdgeSource} predicate.
|
|
17
|
+
*
|
|
18
|
+
* The walk is `walkAppSourceFiles`, platformos-common's anchored expansion of
|
|
19
|
+
* `APP_SOURCE_SUBTREES`, so this file names no directory at all and a bundled `react-app/` is
|
|
20
|
+
* never walked. `edge-sources.spec` pins the scoped result against a whole-tree walk filtered
|
|
21
|
+
* by {@link isEdgeSource}.
|
|
22
|
+
*
|
|
23
|
+
* NOT shared with `buildAppGraph`'s full-build discovery: the two gather DIFFERENT domains —
|
|
24
|
+
* that one takes render entry points (pages + layouts, partials being edge-reached) plus
|
|
25
|
+
* standalone schema nodes, this one takes page + layout + partial. They share the walk
|
|
26
|
+
* primitive and the classifier, which are the parts that must not drift.
|
|
27
|
+
*/
|
|
28
|
+
export declare function enumerateEdgeSources(fs: AbstractFileSystem, rootUri: UriString): Promise<UriString[]>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isEdgeSource = isEdgeSource;
|
|
4
|
+
exports.enumerateEdgeSources = enumerateEdgeSources;
|
|
5
|
+
const platformos_common_1 = require("@platformos/platformos-common");
|
|
6
|
+
/**
|
|
7
|
+
* The canonical definition of an EDGE SOURCE: a liquid file whose own content can declare
|
|
8
|
+
* outgoing edges (a Page, Layout, or Partial). Only these files' add/remove/modify can change
|
|
9
|
+
* any file's set of dependents — `.graphql`/`.yml`/asset files are leaves.
|
|
10
|
+
*
|
|
11
|
+
* "Which files" derives entirely from the file-type classifier, so this predicate never
|
|
12
|
+
* re-encodes the classification. It is ANCHORED on `rootUri`, because a file's type IS its
|
|
13
|
+
* position relative to the project root: unanchored, `tmp/app/lib/x.liquid` is a Partial.
|
|
14
|
+
*/
|
|
15
|
+
function isEdgeSource(uri, rootUri) {
|
|
16
|
+
switch ((0, platformos_common_1.getFileType)(uri, rootUri)) {
|
|
17
|
+
case platformos_common_1.PlatformOSFileType.Layout:
|
|
18
|
+
case platformos_common_1.PlatformOSFileType.Page:
|
|
19
|
+
case platformos_common_1.PlatformOSFileType.Partial:
|
|
20
|
+
return true;
|
|
21
|
+
default:
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Enumerate every edge-source liquid file under a project root — the single canonical primitive
|
|
27
|
+
* for "which files are the graph's edge sources". Consumers never re-derive the walk or the
|
|
28
|
+
* {@link isEdgeSource} predicate.
|
|
29
|
+
*
|
|
30
|
+
* The walk is `walkAppSourceFiles`, platformos-common's anchored expansion of
|
|
31
|
+
* `APP_SOURCE_SUBTREES`, so this file names no directory at all and a bundled `react-app/` is
|
|
32
|
+
* never walked. `edge-sources.spec` pins the scoped result against a whole-tree walk filtered
|
|
33
|
+
* by {@link isEdgeSource}.
|
|
34
|
+
*
|
|
35
|
+
* NOT shared with `buildAppGraph`'s full-build discovery: the two gather DIFFERENT domains —
|
|
36
|
+
* that one takes render entry points (pages + layouts, partials being edge-reached) plus
|
|
37
|
+
* standalone schema nodes, this one takes page + layout + partial. They share the walk
|
|
38
|
+
* primitive and the classifier, which are the parts that must not drift.
|
|
39
|
+
*/
|
|
40
|
+
async function enumerateEdgeSources(fs, rootUri) {
|
|
41
|
+
return (0, platformos_common_1.walkAppSourceFiles)(fs, rootUri, ([uri]) => isEdgeSource(uri, rootUri));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=edge-sources.js.map
|
|
@@ -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 {};
|