@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.
Files changed (120) hide show
  1. package/CHANGELOG.md +511 -8
  2. package/dist/cache-probes.spec.d.ts +1 -0
  3. package/dist/cache-probes.spec.js +62 -0
  4. package/dist/cache-probes.spec.js.map +1 -0
  5. package/dist/cli.js +18 -13
  6. package/dist/cli.js.map +1 -1
  7. package/dist/cli.spec.d.ts +1 -0
  8. package/dist/cli.spec.js +235 -0
  9. package/dist/cli.spec.js.map +1 -0
  10. package/dist/graph/app-index-resolution.spec.d.ts +1 -0
  11. package/dist/graph/app-index-resolution.spec.js +167 -0
  12. package/dist/graph/app-index-resolution.spec.js.map +1 -0
  13. package/dist/graph/asset-resolution.spec.d.ts +1 -0
  14. package/dist/graph/asset-resolution.spec.js +64 -0
  15. package/dist/graph/asset-resolution.spec.js.map +1 -0
  16. package/dist/graph/augment.js +3 -0
  17. package/dist/graph/augment.js.map +1 -1
  18. package/dist/graph/build.d.ts +15 -2
  19. package/dist/graph/build.js +54 -12
  20. package/dist/graph/build.js.map +1 -1
  21. package/dist/graph/build.spec.d.ts +1 -0
  22. package/dist/graph/build.spec.js +138 -0
  23. package/dist/graph/build.spec.js.map +1 -0
  24. package/dist/graph/edge-sources.d.ts +28 -0
  25. package/dist/graph/edge-sources.js +43 -0
  26. package/dist/graph/edge-sources.js.map +1 -0
  27. package/dist/graph/edge-sources.spec.d.ts +1 -0
  28. package/dist/graph/edge-sources.spec.js +125 -0
  29. package/dist/graph/edge-sources.spec.js.map +1 -0
  30. package/dist/graph/extract.spec.d.ts +1 -0
  31. package/dist/graph/extract.spec.js +163 -0
  32. package/dist/graph/extract.spec.js.map +1 -0
  33. package/dist/graph/module.d.ts +60 -7
  34. package/dist/graph/module.js +137 -41
  35. package/dist/graph/module.js.map +1 -1
  36. package/dist/graph/module.spec.d.ts +1 -0
  37. package/dist/graph/module.spec.js +74 -0
  38. package/dist/graph/module.spec.js.map +1 -0
  39. package/dist/graph/query.d.ts +72 -0
  40. package/dist/graph/query.js +140 -0
  41. package/dist/graph/query.js.map +1 -0
  42. package/dist/graph/query.spec.d.ts +1 -0
  43. package/dist/graph/query.spec.js +209 -0
  44. package/dist/graph/query.spec.js.map +1 -0
  45. package/dist/graph/serialize.spec.d.ts +1 -0
  46. package/dist/graph/serialize.spec.js +50 -0
  47. package/dist/graph/serialize.spec.js.map +1 -0
  48. package/dist/graph/structural.spec.d.ts +1 -0
  49. package/dist/graph/structural.spec.js +146 -0
  50. package/dist/graph/structural.spec.js.map +1 -0
  51. package/dist/graph/test-helpers.js +3 -3
  52. package/dist/graph/test-helpers.js.map +1 -1
  53. package/dist/graph/traverse-edges.spec.d.ts +1 -0
  54. package/dist/graph/traverse-edges.spec.js +337 -0
  55. package/dist/graph/traverse-edges.spec.js.map +1 -0
  56. package/dist/graph/traverse.d.ts +51 -20
  57. package/dist/graph/traverse.js +239 -29
  58. package/dist/graph/traverse.js.map +1 -1
  59. package/dist/index.d.ts +5 -1
  60. package/dist/index.js +19 -1
  61. package/dist/index.js.map +1 -1
  62. package/dist/parsers.d.ts +35 -0
  63. package/dist/parsers.js +72 -0
  64. package/dist/parsers.js.map +1 -0
  65. package/dist/parsers.spec.d.ts +1 -0
  66. package/dist/parsers.spec.js +70 -0
  67. package/dist/parsers.spec.js.map +1 -0
  68. package/dist/toSourceCode.d.ts +14 -2
  69. package/dist/toSourceCode.js +23 -19
  70. package/dist/toSourceCode.js.map +1 -1
  71. package/dist/tsconfig.tsbuildinfo +1 -1
  72. package/dist/types.d.ts +102 -3
  73. package/dist/types.js.map +1 -1
  74. package/dist/utils/index.d.ts +1 -1
  75. package/fixtures/asset-edges/app/assets/logo.css +1 -0
  76. package/fixtures/asset-edges/app/assets/site/app.js +1 -0
  77. package/fixtures/asset-edges/app/views/pages/index.liquid +3 -0
  78. package/fixtures/graphql-table/app/graphql/with_table.graphql +5 -0
  79. package/fixtures/graphql-table/app/graphql/without_table.graphql +3 -0
  80. package/fixtures/graphql-table/app/views/pages/index.liquid +4 -0
  81. package/fixtures/layout-edges/app/views/layouts/theme.liquid +4 -0
  82. package/fixtures/layout-edges/app/views/pages/broken.liquid +5 -0
  83. package/fixtures/layout-edges/app/views/pages/index.liquid +5 -0
  84. package/fixtures/schema-nodes/app/schema/blog_post.yml +6 -0
  85. package/fixtures/schema-nodes/app/schema/no_name.yml +3 -0
  86. package/fixtures/schema-nodes/app/views/pages/index.liquid +1 -0
  87. package/fixtures/structural/app/views/pages/about.liquid +1 -0
  88. package/fixtures/structural/app/views/pages/blog/show.liquid +4 -0
  89. package/fixtures/structural/app/views/pages/index.liquid +6 -0
  90. package/fixtures/structural/app/views/pages/rich.liquid +8 -0
  91. package/fixtures/structural/app/views/partials/card.liquid +1 -0
  92. package/fixtures/structural/app/views/partials/documented.liquid +5 -0
  93. package/package.json +7 -5
  94. package/src/cli.spec.ts +37 -31
  95. package/src/cli.ts +31 -15
  96. package/src/graph/augment.ts +4 -0
  97. package/src/graph/build.spec.ts +871 -6
  98. package/src/graph/build.ts +68 -17
  99. package/src/graph/edge-sources.spec.ts +125 -0
  100. package/src/graph/edge-sources.ts +49 -0
  101. package/src/graph/module.spec.ts +168 -0
  102. package/src/graph/module.ts +139 -45
  103. package/src/graph/query.spec.ts +260 -0
  104. package/src/graph/query.ts +154 -0
  105. package/src/graph/serialize.spec.ts +4 -4
  106. package/src/graph/test-helpers.ts +3 -3
  107. package/src/graph/{extract.spec.ts → traverse.spec.ts} +125 -2
  108. package/src/graph/traverse.ts +278 -37
  109. package/src/index.ts +16 -1
  110. package/src/parsers.spec.ts +85 -0
  111. package/src/parsers.ts +75 -0
  112. package/src/toSourceCode.ts +26 -26
  113. package/src/types.ts +106 -7
  114. package/src/utils/index.ts +1 -1
  115. package/dist/getWebComponentMap.d.ts +0 -10
  116. package/dist/getWebComponentMap.js +0 -66
  117. package/dist/getWebComponentMap.js.map +0 -1
  118. package/src/graph/traverse-edges.spec.ts +0 -278
  119. /package/fixtures/skeleton/{assets → app/assets}/app.css +0 -0
  120. /package/fixtures/skeleton/{assets → app/assets}/app.js +0 -0
package/dist/cli.js CHANGED
@@ -10,7 +10,6 @@ const node_path_1 = __importDefault(require("node:path"));
10
10
  const promises_1 = __importDefault(require("node:fs/promises"));
11
11
  const platformos_check_common_1 = require("@platformos/platformos-check-common");
12
12
  const platformos_common_1 = require("@platformos/platformos-common");
13
- const vscode_uri_1 = require("vscode-uri");
14
13
  const build_1 = require("./graph/build");
15
14
  const serialize_1 = require("./graph/serialize");
16
15
  /**
@@ -30,7 +29,7 @@ exports.nodeFileSystem = {
30
29
  async readDirectory(uri) {
31
30
  const entries = await promises_1.default.readdir(platformos_check_common_1.path.fsPath(uri), { withFileTypes: true });
32
31
  return entries.map((entry) => [
33
- platformos_check_common_1.path.join(uri, entry.name),
32
+ platformos_check_common_1.path.childUri(uri, entry.name),
34
33
  entry.isDirectory() ? platformos_common_1.FileType.Directory : platformos_common_1.FileType.File,
35
34
  ]);
36
35
  },
@@ -50,8 +49,9 @@ exports.nodeFileSystem = {
50
49
  /**
51
50
  * Resolves the given root path (absolute, or relative to `process.cwd()`) to the
52
51
  * forward-slash-normalized `file://` URI of the enclosing platformOS project,
53
- * using the same `findRoot` heuristic as the language server (an `app/`,
54
- * `modules/`, `.pos`, or `.platformos-check.yml` marker at or above the path).
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
55
  *
56
56
  * Throws when no project is found, so a typo'd or non-platformOS directory fails
57
57
  * loudly instead of silently producing an empty graph. Resolving via `findRoot`
@@ -61,14 +61,19 @@ exports.nodeFileSystem = {
61
61
  * `path.normalize` (forward slashes), so any lookup must key the same way or it
62
62
  * silently misses on Windows, where raw URIs keep backslashes.
63
63
  */
64
- async function resolveProjectRoot(root, fs) {
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.
65
67
  const absolute = node_path_1.default.isAbsolute(root) ? root : node_path_1.default.resolve(process.cwd(), root);
66
- const startUri = platformos_check_common_1.path.normalize(vscode_uri_1.URI.file(absolute));
67
- const rootUri = await (0, platformos_check_common_1.findRoot)(startUri, (0, platformos_check_common_1.makeFileExists)(fs));
68
+ const { given, root: rootUri } = await (0, platformos_check_common_1.resolveProjectRoot)(absolute, (0, platformos_check_common_1.makeFileExists)(fs));
68
69
  if (!rootUri) {
69
- throw new Error(`Not a platformOS project: ${startUri}\n` +
70
- `No app/, modules/, .pos, or .platformos-check.yml found at or above this path. ` +
71
- `Pass the path to a platformOS app directory.`);
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.`);
72
77
  }
73
78
  return rootUri;
74
79
  }
@@ -80,7 +85,7 @@ async function resolveProjectRoot(root, fs) {
80
85
  */
81
86
  function resolveFileUri(rootUri, file) {
82
87
  if (node_path_1.default.isAbsolute(file)) {
83
- return platformos_check_common_1.path.normalize(vscode_uri_1.URI.file(file));
88
+ return (0, platformos_common_1.uriFromPath)(file);
84
89
  }
85
90
  return platformos_check_common_1.path.join(rootUri, ...file.split(/[\\/]+/).filter(Boolean));
86
91
  }
@@ -92,7 +97,7 @@ function resolveFileUri(rootUri, file) {
92
97
  * `fs` is injectable for testing; it defaults to the node-backed filesystem.
93
98
  */
94
99
  async function buildSerializedGraph(root, fs = exports.nodeFileSystem) {
95
- const graph = await (0, build_1.buildAppGraph)(await resolveProjectRoot(root, fs), { fs });
100
+ const graph = await (0, build_1.buildAppGraph)(await resolveGraphRoot(root, fs), { fs });
96
101
  return (0, serialize_1.serializeAppGraph)(graph);
97
102
  }
98
103
  /**
@@ -108,7 +113,7 @@ async function buildSerializedGraph(root, fs = exports.nodeFileSystem) {
108
113
  * `fs` is injectable for testing; it defaults to the node-backed filesystem.
109
114
  */
110
115
  async function buildSerializedFileDependencies(root, file, fs = exports.nodeFileSystem) {
111
- const rootUri = await resolveProjectRoot(root, fs);
116
+ const rootUri = await resolveGraphRoot(root, fs);
112
117
  const fileUri = resolveFileUri(rootUri, file);
113
118
  const graph = await (0, build_1.buildAppGraph)(rootUri, { fs });
114
119
  const module = graph.modules[fileUri];
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -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 {};
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * The graph resolves `{% render %}` / `{% function %}` / `{% graphql %}` / `layout:`
5
+ * targets through `IDependencies.app`'s index when it is given one.
6
+ *
7
+ * Two things are pinned, and they pull in opposite directions:
8
+ *
9
+ * 1. COST. With an app, a name is answered from the O(1) index and the build lists no
10
+ * directory at all — except for assets, which never use the index by design.
11
+ * 2. ANSWER. The graph must be IDENTICAL with the app, without it, and with an app whose
12
+ * index is only partly populated. The index is a shortcut through `findOrLocate`, not
13
+ * a second resolution rule, so every arm here compares whole graphs.
14
+ *
15
+ * The no-app arm is the control for the cost claim: it shows these very lookups DO cost
16
+ * listings when nothing can answer them, so "no directories listed" is caused by the
17
+ * index rather than by a fixture with nothing to resolve.
18
+ */
19
+ const platformos_check_common_1 = require("@platformos/platformos-check-common");
20
+ const platformos_common_1 = require("@platformos/platformos-common");
21
+ const platformos_check_node_1 = require("@platformos/platformos-check-node");
22
+ const vitest_1 = require("vitest");
23
+ const index_1 = require("../index");
24
+ const utils_1 = require("../utils");
25
+ const test_helpers_1 = require("./test-helpers");
26
+ const moduleEdges = platformos_check_common_1.path.join(test_helpers_1.fixturesRoot, 'module-edges');
27
+ /** The real filesystem, with every directory listing recorded. */
28
+ function recordingFs() {
29
+ const listedDirectories = [];
30
+ const fs = {
31
+ stat: (uri) => platformos_check_node_1.NodeFileSystem.stat(uri),
32
+ readFile: (uri) => platformos_check_node_1.NodeFileSystem.readFile(uri),
33
+ readDirectory: (uri) => {
34
+ listedDirectories.push(uri);
35
+ return platformos_check_node_1.NodeFileSystem.readDirectory(uri);
36
+ },
37
+ };
38
+ return { fs, listedDirectories };
39
+ }
40
+ /** Every source file under the root, classified — the app the language server holds. */
41
+ async function wholeApp(rootUri, fs) {
42
+ return platformos_common_1.App.fromPaths(rootUri, await (0, platformos_common_1.walkAppSourceFiles)(fs, rootUri), fs);
43
+ }
44
+ /** An app that knows the entry points and nothing else, so every target is an index MISS. */
45
+ async function pagesOnlyApp(rootUri, fs) {
46
+ const whole = await wholeApp(rootUri, fs);
47
+ return platformos_common_1.App.fromPaths(rootUri, whole.pages().map((file) => file.uri), fs);
48
+ }
49
+ /**
50
+ * Build the fixture's graph from its pages and layouts, recording what it touched.
51
+ *
52
+ * `entryPoints` are passed explicitly — a discovering build walks the project first, and
53
+ * those listings would swamp the ones under test. The scope is the same one
54
+ * `buildAppGraph` would have discovered for these fixtures.
55
+ */
56
+ async function buildRecording(rootUri, makeApp) {
57
+ const { fs, listedDirectories } = recordingFs();
58
+ const entryPointsApp = await wholeApp(rootUri, fs);
59
+ const entryPoints = [...entryPointsApp.pages(), ...entryPointsApp.layouts()].map((file) => file.uri);
60
+ const app = makeApp ? await makeApp(rootUri, fs) : undefined;
61
+ const sourcesRead = [];
62
+ const getSourceCode = (0, test_helpers_1.makeGetSourceCode)(fs);
63
+ // Everything above is fixture setup — the walks it performed are not what is measured.
64
+ listedDirectories.length = 0;
65
+ const graph = await (0, index_1.buildAppGraph)(rootUri, {
66
+ fs,
67
+ app,
68
+ getSourceCode: (uri) => {
69
+ sourcesRead.push(uri);
70
+ return getSourceCode(uri);
71
+ },
72
+ }, entryPoints);
73
+ return {
74
+ graph,
75
+ // SORTED, not in call order: entry points are traversed concurrently, so which
76
+ // lookup reaches the filesystem first is a scheduling detail. WHICH directories a
77
+ // build has to list is the claim.
78
+ listedDirectories: (0, utils_1.unique)(listedDirectories).sort(),
79
+ sourcesRead: (0, utils_1.unique)(sourcesRead).sort(),
80
+ };
81
+ }
82
+ const dir = (rootUri, relative) => platformos_check_common_1.path.join(rootUri, ...relative.split('/'));
83
+ const referenceKey = (reference) => [
84
+ reference.source.uri,
85
+ reference.source.range?.join(':') ?? '',
86
+ reference.kind,
87
+ reference.type,
88
+ ].join('|');
89
+ /**
90
+ * The graph with every node's REVERSE index (`references`) in a stable order.
91
+ *
92
+ * A node's dependents are appended as each caller finishes traversing, and entry points
93
+ * are traversed concurrently — so their order tracks how long each resolution took,
94
+ * which is precisely what an index changes. `dependencies` are deliberately NOT sorted:
95
+ * those come from one file's visit in source order, so a difference there would be a
96
+ * real one and must still fail.
97
+ */
98
+ function canonical(graph) {
99
+ const sortReferences = (module) => ({
100
+ ...module,
101
+ references: [...module.references].sort((a, b) => referenceKey(a).localeCompare(referenceKey(b))),
102
+ });
103
+ return {
104
+ ...graph,
105
+ entryPoints: graph.entryPoints.map(sortReferences),
106
+ modules: Object.fromEntries(Object.entries(graph.modules).map(([uri, module]) => [uri, sortReferences(module)])),
107
+ };
108
+ }
109
+ (0, vitest_1.describe)('a graph build over a project with an App index', () => {
110
+ let indexed;
111
+ let unindexed;
112
+ let partialIndex;
113
+ (0, vitest_1.beforeAll)(async () => {
114
+ indexed = await buildRecording(test_helpers_1.skeleton, wholeApp);
115
+ unindexed = await buildRecording(test_helpers_1.skeleton);
116
+ partialIndex = await buildRecording(test_helpers_1.skeleton, pagesOnlyApp);
117
+ });
118
+ (0, vitest_1.it)('lists no directory but the asset one, because the index answers every name', () => {
119
+ // `app/assets` is here on purpose: `findOrLocate` never indexes an asset, since
120
+ // nothing reads one and the only question is whether it still exists on disk.
121
+ (0, vitest_1.expect)(indexed.listedDirectories).toEqual([dir(test_helpers_1.skeleton, 'app/assets')]);
122
+ });
123
+ (0, vitest_1.it)('lists a directory per candidate when there is no index to answer from', () => {
124
+ (0, vitest_1.expect)(unindexed.listedDirectories).toEqual([
125
+ dir(test_helpers_1.skeleton, 'app/assets'),
126
+ dir(test_helpers_1.skeleton, 'app/views/layouts'),
127
+ dir(test_helpers_1.skeleton, 'app/views/partials'),
128
+ ]);
129
+ });
130
+ (0, vitest_1.it)('builds the same graph with the index as without it', () => {
131
+ (0, vitest_1.expect)(canonical(indexed.graph)).toEqual(canonical(unindexed.graph));
132
+ });
133
+ (0, vitest_1.it)('falls back to the filesystem for a name the index does not hold', () => {
134
+ (0, vitest_1.expect)(canonical(partialIndex.graph)).toEqual(canonical(unindexed.graph));
135
+ // And the miss really was a miss: the partial and layout directories were listed,
136
+ // so the equality above is not an app that quietly answered everything.
137
+ (0, vitest_1.expect)(partialIndex.listedDirectories).toEqual(unindexed.listedDirectories);
138
+ });
139
+ (0, vitest_1.it)('never asks for an asset source code, only for the files it traverses', () => {
140
+ // An Asset node is a leaf whose only fact is existence (an `fs.stat`), so `app.js`
141
+ // and `app.css` are absent here — which is why an App backing a graph needs no
142
+ // `.js`/image parsers. Every Liquid file in the fixture IS read: the absence above
143
+ // is about assets, not about a build that read nothing.
144
+ (0, vitest_1.expect)(indexed.sourcesRead).toEqual([
145
+ platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'views', 'layouts', 'application.liquid'),
146
+ platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'views', 'pages', 'index.liquid'),
147
+ platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'views', 'partials', 'child.liquid'),
148
+ platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'views', 'partials', 'header.liquid'),
149
+ platformos_check_common_1.path.join(test_helpers_1.skeleton, 'app', 'views', 'partials', 'parent.liquid'),
150
+ ].sort());
151
+ });
152
+ });
153
+ (0, vitest_1.describe)('a module-prefixed name resolved through an App index', () => {
154
+ let indexed;
155
+ let unindexed;
156
+ (0, vitest_1.beforeAll)(async () => {
157
+ indexed = await buildRecording(moduleEdges, wholeApp);
158
+ unindexed = await buildRecording(moduleEdges);
159
+ });
160
+ (0, vitest_1.it)('costs no listing at all — this fixture has no assets to except', () => {
161
+ (0, vitest_1.expect)(indexed.listedDirectories).toEqual([]);
162
+ });
163
+ (0, vitest_1.it)('resolves `modules/my_module/…` to the same files the candidate walk finds', () => {
164
+ (0, vitest_1.expect)(canonical(indexed.graph)).toEqual(canonical(unindexed.graph));
165
+ });
166
+ });
167
+ //# sourceMappingURL=app-index-resolution.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-index-resolution.spec.js","sourceRoot":"","sources":["../../src/graph/app-index-resolution.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const platformos_common_1 = require("@platformos/platformos-common");
4
+ const vitest_1 = require("vitest");
5
+ const vscode_uri_1 = require("vscode-uri");
6
+ const module_1 = require("./module");
7
+ const ROOT = 'file:///project';
8
+ const emptyGraph = () => ({ rootUri: ROOT, entryPoints: [], modules: {} });
9
+ /**
10
+ * Assets follow exactly the same placement rules as every other platformOS file type:
11
+ * `app/assets/` or `modules/<name>/{public,private}/assets/`. Resolution goes through
12
+ * platformos-common, so the graph cannot disagree with `DocumentsLocator` about where
13
+ * `{{ 'app.js' | asset_url }}` points.
14
+ */
15
+ (0, vitest_1.describe)('asset reference resolution', () => {
16
+ (0, vitest_1.it)("resolves 'app.js' to app/assets/app.js", () => {
17
+ (0, vitest_1.expect)((0, module_1.getAssetModule)(emptyGraph(), 'app.js').uri).toBe(`${ROOT}/app/assets/app.js`);
18
+ });
19
+ (0, vitest_1.it)('keeps a subdirectory instead of collapsing to a basename', () => {
20
+ (0, vitest_1.expect)((0, module_1.getAssetModule)(emptyGraph(), 'styles/theme.css').uri).toBe(`${ROOT}/app/assets/styles/theme.css`);
21
+ });
22
+ (0, vitest_1.it)('routes a modules/<name>/ reference into that module, not into app/assets', () => {
23
+ (0, vitest_1.expect)((0, module_1.getAssetModule)(emptyGraph(), 'modules/admin/app.css').uri).toBe(`${ROOT}/app/modules/admin/public/assets/app.css`);
24
+ });
25
+ (0, vitest_1.it)('ignores a reference with an extension no asset uses', () => {
26
+ (0, vitest_1.expect)((0, module_1.getAssetModule)(emptyGraph(), 'notes.txt')).toBe(undefined);
27
+ });
28
+ (0, vitest_1.it)('agrees with DocumentsLocator for an asset that exists', async () => {
29
+ const assetUri = `${ROOT}/app/assets/app.js`;
30
+ const locator = new platformos_common_1.DocumentsLocator({
31
+ stat: async (uri) => {
32
+ if (uri !== assetUri)
33
+ throw new Error(`ENOENT: ${uri}`);
34
+ return { type: platformos_common_1.FileType.File, size: 0 };
35
+ },
36
+ readFile: async () => '',
37
+ // Resolution reads the candidate directory's listing, not a stat per spelling.
38
+ readDirectory: async (uri) => {
39
+ if (uri !== `${ROOT}/app/assets`)
40
+ throw new Error(`ENOENT: ${uri}`);
41
+ return [[assetUri, platformos_common_1.FileType.File]];
42
+ },
43
+ });
44
+ (0, vitest_1.expect)((0, module_1.getAssetModule)(emptyGraph(), 'app.js').uri).toBe(await locator.locate(vscode_uri_1.URI.parse(ROOT), 'asset', 'app.js'));
45
+ });
46
+ (0, vitest_1.it)('classifies an asset URI as an asset module without reconstructing its path', () => {
47
+ const nested = `${ROOT}/app/assets/styles/theme.css`;
48
+ const moduleAsset = `${ROOT}/modules/admin/private/assets/app.css`;
49
+ (0, vitest_1.expect)((0, module_1.getModule)(emptyGraph(), nested)).toMatchObject({
50
+ type: "Asset" /* ModuleType.Asset */,
51
+ uri: nested,
52
+ });
53
+ // A module ORIGINAL keeps its own path — resolving by name would have moved it to
54
+ // the app-overwrite slot.
55
+ (0, vitest_1.expect)((0, module_1.getModule)(emptyGraph(), moduleAsset)).toMatchObject({
56
+ type: "Asset" /* ModuleType.Asset */,
57
+ uri: moduleAsset,
58
+ });
59
+ });
60
+ (0, vitest_1.it)('does not treat a root-level assets/ path as part of the app', () => {
61
+ (0, vitest_1.expect)((0, module_1.getModule)(emptyGraph(), `${ROOT}/assets/app.js`)).toBe(undefined);
62
+ });
63
+ });
64
+ //# sourceMappingURL=asset-resolution.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-resolution.spec.js","sourceRoot":"","sources":["../../src/graph/asset-resolution.spec.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,9 @@ const utils_1 = require("../utils");
7
7
  function augmentDependencies(rootUri, ideps) {
8
8
  return {
9
9
  fs: ideps.fs,
10
+ // Passed through as given. There is nothing to default: an absent app means the
11
+ // caller has none, and `DocumentsLocator` already owns what to do then.
12
+ app: ideps.app,
10
13
  // parse at most once
11
14
  getSourceCode: (0, platformos_check_common_1.memoize)(ideps.getSourceCode ??
12
15
  async function defaultGetSourceCode(uri) {
@@ -1 +1 @@
1
- {"version":3,"file":"augment.js","sourceRoot":"","sources":["../../src/graph/augment.ts"],"names":[],"mappings":";;AAKA,kDAcC;AAnBD,iFAAoE;AACpE,kDAA+C;AAE/C,oCAAoC;AAEpC,SAAgB,mBAAmB,CAAC,OAAe,EAAE,KAAoB;IACvE,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QAEZ,qBAAqB;QACrB,aAAa,EAAE,IAAA,iCAAO,EACpB,KAAK,CAAC,aAAa;YACjB,KAAK,UAAU,oBAAoB,CAAC,GAAG;gBACrC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC9C,OAAO,IAAA,2BAAY,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACrC,CAAC,EACH,gBAAQ,CACT;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"augment.js","sourceRoot":"","sources":["../../src/graph/augment.ts"],"names":[],"mappings":";;AAKA,kDAkBC;AAvBD,iFAAoE;AACpE,kDAA+C;AAE/C,oCAAoC;AAEpC,SAAgB,mBAAmB,CAAC,OAAe,EAAE,KAAoB;IACvE,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QAEZ,gFAAgF;QAChF,wEAAwE;QACxE,GAAG,EAAE,KAAK,CAAC,GAAG;QAEd,qBAAqB;QACrB,aAAa,EAAE,IAAA,iCAAO,EACpB,KAAK,CAAC,aAAa;YACjB,KAAK,UAAU,oBAAoB,CAAC,GAAG;gBACrC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC9C,OAAO,IAAA,2BAAY,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACrC,CAAC,EACH,gBAAQ,CACT;KACF,CAAC;AACJ,CAAC"}