@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,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* TASK-74 phase B — staleness probes for the graph's caches. THROWAWAY.
|
|
5
|
+
*/
|
|
6
|
+
const vitest_1 = require("vitest");
|
|
7
|
+
const augment_1 = require("./graph/augment");
|
|
8
|
+
const module_1 = require("./graph/module");
|
|
9
|
+
const ROOT = 'file:///project';
|
|
10
|
+
const PARTIAL = `${ROOT}/app/views/partials/card.liquid`;
|
|
11
|
+
const emptyGraph = () => ({ rootUri: ROOT, modules: {}, entryPoints: [] });
|
|
12
|
+
(0, vitest_1.describe)('PROBE: ModuleCache (graph/module.ts)', () => {
|
|
13
|
+
/**
|
|
14
|
+
* Not a content cache: a module carries no source, so it cannot go stale. It exists so a
|
|
15
|
+
* file reached from two edges is ONE node, and its lifetime is the graph's.
|
|
16
|
+
*/
|
|
17
|
+
(0, vitest_1.it)('returns one node per (graph, uri), and a new graph gets its own', () => {
|
|
18
|
+
const graph = emptyGraph();
|
|
19
|
+
const first = (0, module_1.getModule)(graph, PARTIAL);
|
|
20
|
+
const again = (0, module_1.getModule)(graph, PARTIAL);
|
|
21
|
+
const inAnotherGraph = (0, module_1.getModule)(emptyGraph(), PARTIAL);
|
|
22
|
+
(0, vitest_1.expect)({
|
|
23
|
+
oneNodePerGraph: first === again,
|
|
24
|
+
separatePerGraph: first !== inAnotherGraph,
|
|
25
|
+
sameUri: first?.uri === inAnotherGraph?.uri,
|
|
26
|
+
}).toEqual({ oneNodePerGraph: true, separatePerGraph: true, sameUri: true });
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.describe)('PROBE: augmentDependencies getSourceCode memo (graph/augment.ts)', () => {
|
|
30
|
+
(0, vitest_1.it)('reads a URI once per build, and a new build re-reads it', async () => {
|
|
31
|
+
const files = { [PARTIAL]: 'first' };
|
|
32
|
+
let reads = 0;
|
|
33
|
+
const ideps = {
|
|
34
|
+
fs: {
|
|
35
|
+
async readFile(uri) {
|
|
36
|
+
reads++;
|
|
37
|
+
return files[uri];
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
const build = (0, augment_1.augmentDependencies)(ROOT, ideps);
|
|
42
|
+
const before = await build.getSourceCode(PARTIAL);
|
|
43
|
+
files[PARTIAL] = 'second';
|
|
44
|
+
const afterEditSameBuild = await build.getSourceCode(PARTIAL);
|
|
45
|
+
// A build is one traversal; the next one augments its own deps and therefore re-reads.
|
|
46
|
+
const nextBuild = (0, augment_1.augmentDependencies)(ROOT, ideps);
|
|
47
|
+
const afterEditNextBuild = await nextBuild.getSourceCode(PARTIAL);
|
|
48
|
+
(0, vitest_1.expect)({
|
|
49
|
+
before: before.source,
|
|
50
|
+
afterEditSameBuild: afterEditSameBuild.source,
|
|
51
|
+
afterEditNextBuild: afterEditNextBuild.source,
|
|
52
|
+
reads,
|
|
53
|
+
}).toEqual({
|
|
54
|
+
before: 'first',
|
|
55
|
+
// Stale WITHIN a build, which is the point: a traversal must see one snapshot.
|
|
56
|
+
afterEditSameBuild: 'first',
|
|
57
|
+
afterEditNextBuild: 'second',
|
|
58
|
+
reads: 2,
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=cache-probes.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-probes.spec.js","sourceRoot":"","sources":["../src/cache-probes.spec.ts"],"names":[],"mappings":";;AAAA;;GAEG;AACH,mCAA8C;AAE9C,6CAAsD;AACtD,2CAA2C;AAG3C,MAAM,IAAI,GAAG,iBAAiB,CAAC;AAC/B,MAAM,OAAO,GAAG,GAAG,IAAI,iCAAiC,CAAC;AAEzD,MAAM,UAAU,GAAG,GAAa,EAAE,CAChC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAwB,CAAC;AAE3E,IAAA,iBAAQ,EAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD;;;OAGG;IACH,IAAA,WAAE,EAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAE3B,MAAM,KAAK,GAAG,IAAA,kBAAS,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,IAAA,kBAAS,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,cAAc,GAAG,IAAA,kBAAS,EAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;QAExD,IAAA,eAAM,EAAC;YACL,eAAe,EAAE,KAAK,KAAK,KAAK;YAChC,gBAAgB,EAAE,KAAK,KAAK,cAAc;YAC1C,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,cAAc,EAAE,GAAG;SAC5C,CAAC,CAAC,OAAO,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,kEAAkE,EAAE,GAAG,EAAE;IAChF,IAAA,WAAE,EAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,KAAK,GAA2B,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QAC7D,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,KAAK,GAAG;YACZ,EAAE,EAAE;gBACF,KAAK,CAAC,QAAQ,CAAC,GAAW;oBACxB,KAAK,EAAE,CAAC;oBACR,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;gBACpB,CAAC;aACF;SAC0B,CAAC;QAE9B,MAAM,KAAK,GAAG,IAAA,6BAAmB,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAClD,KAAK,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC;QAC1B,MAAM,kBAAkB,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAE9D,uFAAuF;QACvF,MAAM,SAAS,GAAG,IAAA,6BAAmB,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnD,MAAM,kBAAkB,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAElE,IAAA,eAAM,EAAC;YACL,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,kBAAkB,EAAE,kBAAkB,CAAC,MAAM;YAC7C,kBAAkB,EAAE,kBAAkB,CAAC,MAAM;YAC7C,KAAK;SACN,CAAC,CAAC,OAAO,CAAC;YACT,MAAM,EAAE,OAAO;YACf,+EAA+E;YAC/E,kBAAkB,EAAE,OAAO;YAC3B,kBAAkB,EAAE,QAAQ;YAC5B,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AbstractFileSystem } from '@platformos/platformos-common';
|
|
2
|
+
import { Reference, SerializableGraph } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* A self-contained {@link AbstractFileSystem} backed by `node:fs`.
|
|
5
|
+
*
|
|
6
|
+
* The graph driver speaks file URIs, so every method converts the incoming URI
|
|
7
|
+
* to a native path with `path.fsPath` and re-emits child URIs with `path.join`
|
|
8
|
+
* (which preserves the `file://` scheme). This mirrors `NodeFileSystem` from
|
|
9
|
+
* `@platformos/platformos-check-node` exactly, but is inlined here so the CLI
|
|
10
|
+
* runs with only this package's own dependencies — `platformos-check-node` is a
|
|
11
|
+
* dev-only dependency and must not be required at runtime.
|
|
12
|
+
*/
|
|
13
|
+
export declare const nodeFileSystem: AbstractFileSystem;
|
|
14
|
+
/**
|
|
15
|
+
* The dependency and reference edges of a single module, as produced for the
|
|
16
|
+
* CLI's single-file mode.
|
|
17
|
+
*/
|
|
18
|
+
export interface SerializableFileDependencies {
|
|
19
|
+
/** The resolved file URI, as keyed in the graph. */
|
|
20
|
+
uri: string;
|
|
21
|
+
/** Outgoing edges — the modules this file renders/includes/runs/queries. */
|
|
22
|
+
dependencies: Reference[];
|
|
23
|
+
/** Incoming edges — the modules that render/include/run/query this file. */
|
|
24
|
+
references: Reference[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Builds the platformOS app graph for the project rooted at `root` (a native
|
|
28
|
+
* filesystem path, absolute or relative to `process.cwd()`) and returns it in
|
|
29
|
+
* serializable JSON form.
|
|
30
|
+
*
|
|
31
|
+
* `fs` is injectable for testing; it defaults to the node-backed filesystem.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildSerializedGraph(root: string, fs?: AbstractFileSystem): Promise<SerializableGraph>;
|
|
34
|
+
/**
|
|
35
|
+
* Builds the full app graph for `root` and returns the dependency and reference
|
|
36
|
+
* edges of the single module at `file`.
|
|
37
|
+
*
|
|
38
|
+
* The graph is built from its real entry points (every layout and page), not
|
|
39
|
+
* seeded from `file`, so that incoming `references` are complete — the same
|
|
40
|
+
* approach the language server's `AppGraphManager` takes. A file that is not
|
|
41
|
+
* reachable from any entry point therefore has no node in the graph; rather
|
|
42
|
+
* than reporting a misleading empty edge set, this throws.
|
|
43
|
+
*
|
|
44
|
+
* `fs` is injectable for testing; it defaults to the node-backed filesystem.
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildSerializedFileDependencies(root: string, file: string, fs?: AbstractFileSystem): Promise<SerializableFileDependencies>;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.nodeFileSystem = void 0;
|
|
7
|
+
exports.buildSerializedGraph = buildSerializedGraph;
|
|
8
|
+
exports.buildSerializedFileDependencies = buildSerializedFileDependencies;
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
11
|
+
const platformos_check_common_1 = require("@platformos/platformos-check-common");
|
|
12
|
+
const platformos_common_1 = require("@platformos/platformos-common");
|
|
13
|
+
const build_1 = require("./graph/build");
|
|
14
|
+
const serialize_1 = require("./graph/serialize");
|
|
15
|
+
/**
|
|
16
|
+
* A self-contained {@link AbstractFileSystem} backed by `node:fs`.
|
|
17
|
+
*
|
|
18
|
+
* The graph driver speaks file URIs, so every method converts the incoming URI
|
|
19
|
+
* to a native path with `path.fsPath` and re-emits child URIs with `path.join`
|
|
20
|
+
* (which preserves the `file://` scheme). This mirrors `NodeFileSystem` from
|
|
21
|
+
* `@platformos/platformos-check-node` exactly, but is inlined here so the CLI
|
|
22
|
+
* runs with only this package's own dependencies — `platformos-check-node` is a
|
|
23
|
+
* dev-only dependency and must not be required at runtime.
|
|
24
|
+
*/
|
|
25
|
+
exports.nodeFileSystem = {
|
|
26
|
+
async readFile(uri) {
|
|
27
|
+
return promises_1.default.readFile(platformos_check_common_1.path.fsPath(uri), 'utf8');
|
|
28
|
+
},
|
|
29
|
+
async readDirectory(uri) {
|
|
30
|
+
const entries = await promises_1.default.readdir(platformos_check_common_1.path.fsPath(uri), { withFileTypes: true });
|
|
31
|
+
return entries.map((entry) => [
|
|
32
|
+
platformos_check_common_1.path.childUri(uri, entry.name),
|
|
33
|
+
entry.isDirectory() ? platformos_common_1.FileType.Directory : platformos_common_1.FileType.File,
|
|
34
|
+
]);
|
|
35
|
+
},
|
|
36
|
+
async stat(uri) {
|
|
37
|
+
try {
|
|
38
|
+
const stats = await promises_1.default.stat(platformos_check_common_1.path.fsPath(uri));
|
|
39
|
+
return {
|
|
40
|
+
type: stats.isDirectory() ? platformos_common_1.FileType.Directory : platformos_common_1.FileType.File,
|
|
41
|
+
size: stats.size,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
throw new Error(`Failed to get file stat: ${e}`);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Resolves the given root path (absolute, or relative to `process.cwd()`) to the
|
|
51
|
+
* forward-slash-normalized `file://` URI of the enclosing platformOS project,
|
|
52
|
+
* using the same `findRoot` heuristic as the language server (an `app/` — or its
|
|
53
|
+
* legacy `marketplace_builder/` sibling — `modules/`, `.pos`, or
|
|
54
|
+
* `.platformos-check.yml` marker at or above the path).
|
|
55
|
+
*
|
|
56
|
+
* Throws when no project is found, so a typo'd or non-platformOS directory fails
|
|
57
|
+
* loudly instead of silently producing an empty graph. Resolving via `findRoot`
|
|
58
|
+
* also lets the CLI be pointed anywhere inside a project, not just at its root.
|
|
59
|
+
*
|
|
60
|
+
* Normalization is load-bearing: the graph keys every module via `path.join` /
|
|
61
|
+
* `path.normalize` (forward slashes), so any lookup must key the same way or it
|
|
62
|
+
* silently misses on Windows, where raw URIs keep backslashes.
|
|
63
|
+
*/
|
|
64
|
+
async function resolveGraphRoot(root, fs) {
|
|
65
|
+
// Only the cwd-relative step stays here: `process.cwd()` is node-specific, and the resolution
|
|
66
|
+
// itself lives in platformos-check-common so the linter shares it rather than owning a copy.
|
|
67
|
+
const absolute = node_path_1.default.isAbsolute(root) ? root : node_path_1.default.resolve(process.cwd(), root);
|
|
68
|
+
const { given, root: rootUri } = await (0, platformos_check_common_1.resolveProjectRoot)(absolute, (0, platformos_check_common_1.makeFileExists)(fs));
|
|
69
|
+
if (!rootUri) {
|
|
70
|
+
// The marker list is derived rather than restated, so it cannot drift from what findRoot
|
|
71
|
+
// actually looks for. The wording is unchanged from when it was hand-written — this is a
|
|
72
|
+
// refactor, and the existing message assertion is what proves it stayed one.
|
|
73
|
+
const markers = platformos_check_common_1.PROJECT_ROOT_MARKERS.join(', ').replace(/, ([^,]*)$/, ', or $1');
|
|
74
|
+
throw new Error(`Not a platformOS project: ${given}\n` +
|
|
75
|
+
`No ${markers} found ` +
|
|
76
|
+
`at or above this path. Pass the path to a platformOS app directory.`);
|
|
77
|
+
}
|
|
78
|
+
return rootUri;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Resolves the single-file argument to a graph module key. An absolute path is
|
|
82
|
+
* taken as-is; a relative path is resolved against the project **root** (not
|
|
83
|
+
* `process.cwd()`), matching the natural "a file within this project" mental
|
|
84
|
+
* model — only files under the root can appear in the graph anyway.
|
|
85
|
+
*/
|
|
86
|
+
function resolveFileUri(rootUri, file) {
|
|
87
|
+
if (node_path_1.default.isAbsolute(file)) {
|
|
88
|
+
return (0, platformos_common_1.uriFromPath)(file);
|
|
89
|
+
}
|
|
90
|
+
return platformos_check_common_1.path.join(rootUri, ...file.split(/[\\/]+/).filter(Boolean));
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Builds the platformOS app graph for the project rooted at `root` (a native
|
|
94
|
+
* filesystem path, absolute or relative to `process.cwd()`) and returns it in
|
|
95
|
+
* serializable JSON form.
|
|
96
|
+
*
|
|
97
|
+
* `fs` is injectable for testing; it defaults to the node-backed filesystem.
|
|
98
|
+
*/
|
|
99
|
+
async function buildSerializedGraph(root, fs = exports.nodeFileSystem) {
|
|
100
|
+
const graph = await (0, build_1.buildAppGraph)(await resolveGraphRoot(root, fs), { fs });
|
|
101
|
+
return (0, serialize_1.serializeAppGraph)(graph);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Builds the full app graph for `root` and returns the dependency and reference
|
|
105
|
+
* edges of the single module at `file`.
|
|
106
|
+
*
|
|
107
|
+
* The graph is built from its real entry points (every layout and page), not
|
|
108
|
+
* seeded from `file`, so that incoming `references` are complete — the same
|
|
109
|
+
* approach the language server's `AppGraphManager` takes. A file that is not
|
|
110
|
+
* reachable from any entry point therefore has no node in the graph; rather
|
|
111
|
+
* than reporting a misleading empty edge set, this throws.
|
|
112
|
+
*
|
|
113
|
+
* `fs` is injectable for testing; it defaults to the node-backed filesystem.
|
|
114
|
+
*/
|
|
115
|
+
async function buildSerializedFileDependencies(root, file, fs = exports.nodeFileSystem) {
|
|
116
|
+
const rootUri = await resolveGraphRoot(root, fs);
|
|
117
|
+
const fileUri = resolveFileUri(rootUri, file);
|
|
118
|
+
const graph = await (0, build_1.buildAppGraph)(rootUri, { fs });
|
|
119
|
+
const module = graph.modules[fileUri];
|
|
120
|
+
if (!module) {
|
|
121
|
+
throw new Error(`File is not part of the app graph: ${fileUri}\n` +
|
|
122
|
+
`It must exist and be reachable from a layout or page entry point. ` +
|
|
123
|
+
`Check the path is correct and inside the project root (${rootUri}).`);
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
uri: module.uri,
|
|
127
|
+
dependencies: module.dependencies,
|
|
128
|
+
references: module.references,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cli.spec.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
7
|
+
const platformos_check_common_1 = require("@platformos/platformos-check-common");
|
|
8
|
+
const platformos_common_1 = require("@platformos/platformos-common");
|
|
9
|
+
const vitest_1 = require("vitest");
|
|
10
|
+
const cli_1 = require("./cli");
|
|
11
|
+
const test_helpers_1 = require("./graph/test-helpers");
|
|
12
|
+
const skeletonPath = platformos_check_common_1.path.fsPath(test_helpers_1.skeleton);
|
|
13
|
+
const p = (rel) => platformos_check_common_1.path.join(test_helpers_1.skeleton, ...rel.split('/'));
|
|
14
|
+
const fsPathOf = (rel) => node_path_1.default.join(skeletonPath, ...rel.split('/'));
|
|
15
|
+
(0, vitest_1.describe)('platformos-graph CLI: buildSerializedGraph', () => {
|
|
16
|
+
(0, vitest_1.it)('serializes the full node and edge set for a project path', async () => {
|
|
17
|
+
const graph = await (0, cli_1.buildSerializedGraph)(skeletonPath);
|
|
18
|
+
// Root is the project path re-expressed as a file URI.
|
|
19
|
+
(0, vitest_1.expect)(graph.rootUri).toBe((0, platformos_common_1.uriFromPath)(skeletonPath));
|
|
20
|
+
// Whole node set, sorted by URI so the assertion is order-independent.
|
|
21
|
+
// (`app/assets/*` sorts ahead of `app/views/*`.)
|
|
22
|
+
(0, vitest_1.expect)([...graph.nodes].sort((a, b) => a.uri.localeCompare(b.uri))).toEqual([
|
|
23
|
+
{
|
|
24
|
+
uri: p('app/assets/app.css'),
|
|
25
|
+
type: "Asset" /* ModuleType.Asset */,
|
|
26
|
+
kind: 'unused',
|
|
27
|
+
exists: true,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
uri: p('app/assets/app.js'),
|
|
31
|
+
type: "Asset" /* ModuleType.Asset */,
|
|
32
|
+
kind: 'unused',
|
|
33
|
+
exists: true,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
uri: p('app/views/layouts/application.liquid'),
|
|
37
|
+
type: "Liquid" /* ModuleType.Liquid */,
|
|
38
|
+
kind: "layout" /* LiquidModuleKind.Layout */,
|
|
39
|
+
exists: true,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
uri: p('app/views/pages/index.liquid'),
|
|
43
|
+
type: "Liquid" /* ModuleType.Liquid */,
|
|
44
|
+
kind: "page" /* LiquidModuleKind.Page */,
|
|
45
|
+
exists: true,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
uri: p('app/views/partials/child.liquid'),
|
|
49
|
+
type: "Liquid" /* ModuleType.Liquid */,
|
|
50
|
+
kind: "partial" /* LiquidModuleKind.Partial */,
|
|
51
|
+
exists: true,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
uri: p('app/views/partials/header.liquid'),
|
|
55
|
+
type: "Liquid" /* ModuleType.Liquid */,
|
|
56
|
+
kind: "partial" /* LiquidModuleKind.Partial */,
|
|
57
|
+
exists: true,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
uri: p('app/views/partials/parent.liquid'),
|
|
61
|
+
type: "Liquid" /* ModuleType.Liquid */,
|
|
62
|
+
kind: "partial" /* LiquidModuleKind.Partial */,
|
|
63
|
+
exists: true,
|
|
64
|
+
},
|
|
65
|
+
]);
|
|
66
|
+
// Whole edge set, reduced to (source, target, type, kind) and sorted, so an
|
|
67
|
+
// extra, missing, or mis-kinded edge fails the assertion.
|
|
68
|
+
const edges = graph.edges
|
|
69
|
+
.map((edge) => ({
|
|
70
|
+
source: edge.source.uri,
|
|
71
|
+
target: edge.target.uri,
|
|
72
|
+
type: edge.type,
|
|
73
|
+
kind: edge.kind,
|
|
74
|
+
}))
|
|
75
|
+
.sort((a, b) => a.source.localeCompare(b.source) || a.target.localeCompare(b.target));
|
|
76
|
+
(0, vitest_1.expect)(edges).toEqual([
|
|
77
|
+
{
|
|
78
|
+
source: p('app/views/layouts/application.liquid'),
|
|
79
|
+
target: p('app/assets/app.css'),
|
|
80
|
+
type: 'direct',
|
|
81
|
+
kind: 'asset',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
source: p('app/views/layouts/application.liquid'),
|
|
85
|
+
target: p('app/assets/app.js'),
|
|
86
|
+
type: 'direct',
|
|
87
|
+
kind: 'asset',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
source: p('app/views/layouts/application.liquid'),
|
|
91
|
+
target: p('app/views/partials/header.liquid'),
|
|
92
|
+
type: 'direct',
|
|
93
|
+
kind: 'render',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
source: p('app/views/pages/index.liquid'),
|
|
97
|
+
target: p('app/views/layouts/application.liquid'),
|
|
98
|
+
type: 'direct',
|
|
99
|
+
kind: 'layout',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
source: p('app/views/pages/index.liquid'),
|
|
103
|
+
target: p('app/views/partials/parent.liquid'),
|
|
104
|
+
type: 'direct',
|
|
105
|
+
kind: 'render',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
source: p('app/views/partials/header.liquid'),
|
|
109
|
+
target: p('app/views/partials/child.liquid'),
|
|
110
|
+
type: 'direct',
|
|
111
|
+
kind: 'render',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
source: p('app/views/partials/parent.liquid'),
|
|
115
|
+
target: p('app/views/partials/child.liquid'),
|
|
116
|
+
type: 'direct',
|
|
117
|
+
kind: 'render',
|
|
118
|
+
},
|
|
119
|
+
]);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
(0, vitest_1.describe)('platformos-graph CLI: nodeFileSystem', () => {
|
|
123
|
+
(0, vitest_1.it)('reads a file by URI', async () => {
|
|
124
|
+
const uri = platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'assets', 'app.js');
|
|
125
|
+
(0, vitest_1.expect)(await cli_1.nodeFileSystem.readFile(uri)).toBe('// Skeleton app bundle (asset reference target).\n');
|
|
126
|
+
});
|
|
127
|
+
(0, vitest_1.it)('stats a directory and a file', async () => {
|
|
128
|
+
(0, vitest_1.expect)(await cli_1.nodeFileSystem.stat(platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'assets'))).toEqual({
|
|
129
|
+
type: platformos_common_1.FileType.Directory,
|
|
130
|
+
size: vitest_1.expect.any(Number),
|
|
131
|
+
});
|
|
132
|
+
(0, vitest_1.expect)(await cli_1.nodeFileSystem.stat(platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'assets', 'app.css'))).toEqual({
|
|
133
|
+
type: platformos_common_1.FileType.File,
|
|
134
|
+
size: vitest_1.expect.any(Number),
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
(0, vitest_1.it)('lists a directory as [childUri, FileType] tuples', async () => {
|
|
138
|
+
const entries = await cli_1.nodeFileSystem.readDirectory(platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'assets'));
|
|
139
|
+
(0, vitest_1.expect)([...entries].sort((a, b) => a[0].localeCompare(b[0]))).toEqual([
|
|
140
|
+
[platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'assets', 'app.css'), platformos_common_1.FileType.File],
|
|
141
|
+
[platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'assets', 'app.js'), platformos_common_1.FileType.File],
|
|
142
|
+
]);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
(0, vitest_1.describe)('platformos-graph CLI: buildSerializedFileDependencies', () => {
|
|
146
|
+
const edge = (ref) => ({
|
|
147
|
+
source: ref.source.uri,
|
|
148
|
+
target: ref.target.uri,
|
|
149
|
+
type: ref.type,
|
|
150
|
+
kind: ref.kind,
|
|
151
|
+
});
|
|
152
|
+
(0, vitest_1.it)('returns the outgoing and incoming edges of a single file', async () => {
|
|
153
|
+
const result = await (0, cli_1.buildSerializedFileDependencies)(skeletonPath, fsPathOf('app/views/partials/parent.liquid'));
|
|
154
|
+
(0, vitest_1.expect)(result.uri).toBe(p('app/views/partials/parent.liquid'));
|
|
155
|
+
(0, vitest_1.expect)(result.dependencies.map(edge)).toEqual([
|
|
156
|
+
{
|
|
157
|
+
source: p('app/views/partials/parent.liquid'),
|
|
158
|
+
target: p('app/views/partials/child.liquid'),
|
|
159
|
+
type: 'direct',
|
|
160
|
+
kind: 'render',
|
|
161
|
+
},
|
|
162
|
+
]);
|
|
163
|
+
(0, vitest_1.expect)(result.references.map(edge)).toEqual([
|
|
164
|
+
{
|
|
165
|
+
source: p('app/views/pages/index.liquid'),
|
|
166
|
+
target: p('app/views/partials/parent.liquid'),
|
|
167
|
+
type: 'direct',
|
|
168
|
+
kind: 'render',
|
|
169
|
+
},
|
|
170
|
+
]);
|
|
171
|
+
});
|
|
172
|
+
(0, vitest_1.it)('returns no dependencies for a leaf partial and every incoming reference', async () => {
|
|
173
|
+
const result = await (0, cli_1.buildSerializedFileDependencies)(skeletonPath, fsPathOf('app/views/partials/child.liquid'));
|
|
174
|
+
(0, vitest_1.expect)(result.uri).toBe(p('app/views/partials/child.liquid'));
|
|
175
|
+
(0, vitest_1.expect)(result.dependencies).toEqual([]);
|
|
176
|
+
(0, vitest_1.expect)(result.references.map(edge).sort((a, b) => a.source.localeCompare(b.source))).toEqual([
|
|
177
|
+
{
|
|
178
|
+
source: p('app/views/partials/header.liquid'),
|
|
179
|
+
target: p('app/views/partials/child.liquid'),
|
|
180
|
+
type: 'direct',
|
|
181
|
+
kind: 'render',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
source: p('app/views/partials/parent.liquid'),
|
|
185
|
+
target: p('app/views/partials/child.liquid'),
|
|
186
|
+
type: 'direct',
|
|
187
|
+
kind: 'render',
|
|
188
|
+
},
|
|
189
|
+
]);
|
|
190
|
+
});
|
|
191
|
+
(0, vitest_1.it)('resolves a relative file argument against the project root, not the cwd', async () => {
|
|
192
|
+
const result = await (0, cli_1.buildSerializedFileDependencies)(skeletonPath, 'app/views/partials/parent.liquid');
|
|
193
|
+
(0, vitest_1.expect)(result.uri).toBe(p('app/views/partials/parent.liquid'));
|
|
194
|
+
(0, vitest_1.expect)(result.dependencies.map(edge)).toEqual([
|
|
195
|
+
{
|
|
196
|
+
source: p('app/views/partials/parent.liquid'),
|
|
197
|
+
target: p('app/views/partials/child.liquid'),
|
|
198
|
+
type: 'direct',
|
|
199
|
+
kind: 'render',
|
|
200
|
+
},
|
|
201
|
+
]);
|
|
202
|
+
});
|
|
203
|
+
(0, vitest_1.it)('throws for a file that is not part of the app graph', async () => {
|
|
204
|
+
const missing = fsPathOf('app/views/partials/nonexistent.liquid');
|
|
205
|
+
const missingUri = (0, platformos_common_1.uriFromPath)(missing);
|
|
206
|
+
const rootUri = (0, platformos_common_1.uriFromPath)(skeletonPath);
|
|
207
|
+
const error = await (0, cli_1.buildSerializedFileDependencies)(skeletonPath, missing).catch((e) => e);
|
|
208
|
+
(0, vitest_1.expect)(error).toBeInstanceOf(Error);
|
|
209
|
+
(0, vitest_1.expect)(error.message).toBe(`File is not part of the app graph: ${missingUri}\n` +
|
|
210
|
+
`It must exist and be reachable from a layout or page entry point. ` +
|
|
211
|
+
`Check the path is correct and inside the project root (${rootUri}).`);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
(0, vitest_1.describe)('platformos-graph CLI: project-root validation', () => {
|
|
215
|
+
/**
|
|
216
|
+
* A filesystem where nothing exists. Injected so `findRoot` walks up from the
|
|
217
|
+
* given path entirely in memory — no real disk, no dependency on what sits
|
|
218
|
+
* above the OS temp dir — and deterministically finds no project marker.
|
|
219
|
+
*/
|
|
220
|
+
const emptyFs = {
|
|
221
|
+
stat: () => Promise.reject(new Error('ENOENT')),
|
|
222
|
+
readFile: () => Promise.reject(new Error('ENOENT')),
|
|
223
|
+
readDirectory: () => Promise.resolve([]),
|
|
224
|
+
};
|
|
225
|
+
(0, vitest_1.it)('throws instead of emitting an empty graph for a non-platformOS directory', async () => {
|
|
226
|
+
const dir = node_path_1.default.resolve('no-such-project', 'sub');
|
|
227
|
+
const startUri = (0, platformos_common_1.uriFromPath)(dir);
|
|
228
|
+
const error = await (0, cli_1.buildSerializedGraph)(dir, emptyFs).catch((e) => e);
|
|
229
|
+
(0, vitest_1.expect)(error).toBeInstanceOf(Error);
|
|
230
|
+
(0, vitest_1.expect)(error.message).toBe(`Not a platformOS project: ${startUri}\n` +
|
|
231
|
+
`No app/, marketplace_builder/, modules/, .pos, or .platformos-check.yml found ` +
|
|
232
|
+
`at or above this path. Pass the path to a platformOS app directory.`);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
//# sourceMappingURL=cli.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.spec.js","sourceRoot":"","sources":["../src/cli.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|