@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
@@ -1,278 +0,0 @@
1
- import { path as pathUtils } from '@platformos/platformos-check-common';
2
- import { beforeAll, describe, expect, it } from 'vitest';
3
- import { buildAppGraph } from '../index';
4
- import {
5
- AppGraph,
6
- Dependencies,
7
- LiquidModule,
8
- LiquidModuleKind,
9
- ModuleType,
10
- Reference,
11
- } from '../types';
12
- import { getGraphQLModuleByUri, getPartialModuleByUri } from './module';
13
- import { fixturesRoot, getDependencies } from './test-helpers';
14
-
15
- /**
16
- * The exact source range of `snippet` within `source`. Derived from the fixture
17
- * text (rather than hard-coded offsets) so the assertion is self-documenting
18
- * and survives edits to unrelated lines.
19
- */
20
- function rangeOf(source: string, snippet: string): [number, number] {
21
- const start = source.indexOf(snippet);
22
- if (start < 0) throw new Error(`snippet not found in fixture: ${snippet}`);
23
- return [start, start + snippet.length];
24
- }
25
-
26
- /** A `direct` dependency Reference with no target range (the common case here). */
27
- function directRef(
28
- sourceUri: string,
29
- sourceRange: [number, number],
30
- targetUri: string,
31
- kind: Reference['kind'],
32
- ): Reference {
33
- return {
34
- source: { uri: sourceUri, range: sourceRange },
35
- target: { uri: targetUri },
36
- type: 'direct',
37
- kind,
38
- };
39
- }
40
-
41
- const partialNode = (uri: string, exists: boolean, references: Reference[]): LiquidModule => ({
42
- type: ModuleType.Liquid,
43
- kind: LiquidModuleKind.Partial,
44
- uri,
45
- exists,
46
- dependencies: [],
47
- references,
48
- });
49
-
50
- describe('URI normalization in graph node factories', () => {
51
- const emptyGraph = (): AppGraph => ({
52
- rootUri: 'file:///app',
53
- entryPoints: [],
54
- modules: {},
55
- });
56
-
57
- it('getPartialModuleByUri returns a Partial node with a forward-slash URI', () => {
58
- const mod = getPartialModuleByUri(
59
- emptyGraph(),
60
- 'file:///d:/a/repo\\app\\lib\\queries\\list.liquid',
61
- );
62
- expect(mod).toEqual({
63
- type: ModuleType.Liquid,
64
- kind: LiquidModuleKind.Partial,
65
- uri: 'file:///d:/a/repo/app/lib/queries/list.liquid',
66
- dependencies: [],
67
- references: [],
68
- });
69
- });
70
-
71
- it('getGraphQLModuleByUri returns a GraphQL node with a forward-slash URI', () => {
72
- const mod = getGraphQLModuleByUri(
73
- emptyGraph(),
74
- 'file:///d:/a/repo\\app\\graphql\\find.graphql',
75
- );
76
- expect(mod).toEqual({
77
- type: ModuleType.GraphQL,
78
- kind: 'graphql',
79
- uri: 'file:///d:/a/repo/app/graphql/find.graphql',
80
- dependencies: [],
81
- references: [],
82
- });
83
- });
84
- });
85
-
86
- describe('Graph traversal: {% function %} edges', () => {
87
- const rootUri = pathUtils.join(fixturesRoot, 'function-edges');
88
- const p = (part: string) => pathUtils.join(rootUri, ...part.split('/'));
89
- let graph: AppGraph;
90
- let indexSource: string;
91
- let brokenSource: string;
92
-
93
- beforeAll(async () => {
94
- const dependencies: Dependencies = getDependencies();
95
- graph = await buildAppGraph(rootUri, dependencies);
96
- indexSource = (await dependencies.getSourceCode(p('app/views/pages/index.liquid'))).source;
97
- brokenSource = (await dependencies.getSourceCode(p('app/views/pages/broken.liquid'))).source;
98
- }, 15000);
99
-
100
- it('links a page to the resolved lib query via a single function edge', () => {
101
- const edge = directRef(
102
- p('app/views/pages/index.liquid'),
103
- rangeOf(indexSource, "function items = 'queries/list'"),
104
- p('app/lib/queries/list.liquid'),
105
- 'function',
106
- );
107
- expect(graph.modules[p('app/views/pages/index.liquid')].dependencies).toEqual([edge]);
108
- expect(graph.modules[p('app/lib/queries/list.liquid')]).toEqual(
109
- partialNode(p('app/lib/queries/list.liquid'), true, [edge]),
110
- );
111
- });
112
-
113
- it('records a missing function target as an exists:false node', () => {
114
- const edge = directRef(
115
- p('app/views/pages/broken.liquid'),
116
- rangeOf(brokenSource, "function ghost = 'queries/missing'"),
117
- p('app/lib/queries/missing.liquid'),
118
- 'function',
119
- );
120
- expect(graph.modules[p('app/lib/queries/missing.liquid')]).toEqual(
121
- partialNode(p('app/lib/queries/missing.liquid'), false, [edge]),
122
- );
123
- });
124
- });
125
-
126
- describe('Graph traversal: {% graphql %} edges', () => {
127
- const rootUri = pathUtils.join(fixturesRoot, 'graphql-edges');
128
- const p = (part: string) => pathUtils.join(rootUri, ...part.split('/'));
129
- let graph: AppGraph;
130
- let indexSource: string;
131
- let brokenSource: string;
132
-
133
- const graphqlNode = (uri: string, exists: boolean, references: Reference[]) => ({
134
- type: ModuleType.GraphQL,
135
- kind: 'graphql' as const,
136
- uri,
137
- exists,
138
- dependencies: [],
139
- references,
140
- });
141
-
142
- beforeAll(async () => {
143
- const dependencies: Dependencies = getDependencies();
144
- graph = await buildAppGraph(rootUri, dependencies);
145
- indexSource = (await dependencies.getSourceCode(p('app/views/pages/index.liquid'))).source;
146
- brokenSource = (await dependencies.getSourceCode(p('app/views/pages/broken.liquid'))).source;
147
- }, 15000);
148
-
149
- it('links a page to the resolved .graphql operation via a single graphql edge', () => {
150
- const edge = directRef(
151
- p('app/views/pages/index.liquid'),
152
- rangeOf(indexSource, "graphql posts = 'blog_posts/find', id: '1'"),
153
- p('app/graphql/blog_posts/find.graphql'),
154
- 'graphql',
155
- );
156
- expect(graph.modules[p('app/views/pages/index.liquid')].dependencies).toEqual([edge]);
157
- expect(graph.modules[p('app/graphql/blog_posts/find.graphql')]).toEqual(
158
- graphqlNode(p('app/graphql/blog_posts/find.graphql'), true, [edge]),
159
- );
160
- });
161
-
162
- it('records a missing graphql target as an exists:false GraphQL node', () => {
163
- const edge = directRef(
164
- p('app/views/pages/broken.liquid'),
165
- rangeOf(brokenSource, "graphql ghost = 'blog_posts/missing'"),
166
- p('app/graphql/blog_posts/missing.graphql'),
167
- 'graphql',
168
- );
169
- expect(graph.modules[p('app/graphql/blog_posts/missing.graphql')]).toEqual(
170
- graphqlNode(p('app/graphql/blog_posts/missing.graphql'), false, [edge]),
171
- );
172
- });
173
- });
174
-
175
- describe('Graph traversal: {% include %} edges', () => {
176
- const rootUri = pathUtils.join(fixturesRoot, 'include-edges');
177
- const p = (part: string) => pathUtils.join(rootUri, ...part.split('/'));
178
- let graph: AppGraph;
179
- let indexSource: string;
180
-
181
- beforeAll(async () => {
182
- const dependencies: Dependencies = getDependencies();
183
- graph = await buildAppGraph(rootUri, dependencies);
184
- indexSource = (await dependencies.getSourceCode(p('app/views/pages/index.liquid'))).source;
185
- }, 15000);
186
-
187
- it('tags an include edge with kind "include" (distinct from render)', () => {
188
- const edge = directRef(
189
- p('app/views/pages/index.liquid'),
190
- rangeOf(indexSource, "{% include 'shared/header' %}"),
191
- p('app/views/partials/shared/header.liquid'),
192
- 'include',
193
- );
194
- expect(graph.modules[p('app/views/pages/index.liquid')].dependencies).toEqual([edge]);
195
- expect(graph.modules[p('app/views/partials/shared/header.liquid')]).toEqual(
196
- partialNode(p('app/views/partials/shared/header.liquid'), true, [edge]),
197
- );
198
- });
199
- });
200
-
201
- describe('Graph traversal: {% background %} edges', () => {
202
- const rootUri = pathUtils.join(fixturesRoot, 'background-edges');
203
- const p = (part: string) => pathUtils.join(rootUri, ...part.split('/'));
204
- let graph: AppGraph;
205
- let indexSource: string;
206
- let brokenSource: string;
207
-
208
- beforeAll(async () => {
209
- const dependencies: Dependencies = getDependencies();
210
- graph = await buildAppGraph(rootUri, dependencies);
211
- indexSource = (await dependencies.getSourceCode(p('app/views/pages/index.liquid'))).source;
212
- brokenSource = (await dependencies.getSourceCode(p('app/views/pages/broken.liquid'))).source;
213
- }, 15000);
214
-
215
- it('links a page to the background partial via a single background edge', () => {
216
- const edge = directRef(
217
- p('app/views/pages/index.liquid'),
218
- rangeOf(indexSource, "background job_id = 'jobs/notify', data: 'x'"),
219
- p('app/views/partials/jobs/notify.liquid'),
220
- 'background',
221
- );
222
- expect(graph.modules[p('app/views/pages/index.liquid')].dependencies).toEqual([edge]);
223
- expect(graph.modules[p('app/views/partials/jobs/notify.liquid')]).toEqual(
224
- partialNode(p('app/views/partials/jobs/notify.liquid'), true, [edge]),
225
- );
226
- });
227
-
228
- it('records a missing background target as an exists:false node', () => {
229
- const edge = directRef(
230
- p('app/views/pages/broken.liquid'),
231
- rangeOf(brokenSource, "background job_id = 'jobs/missing'"),
232
- p('app/lib/jobs/missing.liquid'),
233
- 'background',
234
- );
235
- expect(graph.modules[p('app/lib/jobs/missing.liquid')]).toEqual(
236
- partialNode(p('app/lib/jobs/missing.liquid'), false, [edge]),
237
- );
238
- });
239
- });
240
-
241
- describe('Graph traversal: module-namespaced targets (modules/<name>/public/...)', () => {
242
- const rootUri = pathUtils.join(fixturesRoot, 'module-edges');
243
- const p = (part: string) => pathUtils.join(rootUri, ...part.split('/'));
244
- let graph: AppGraph;
245
- let indexSource: string;
246
-
247
- beforeAll(async () => {
248
- const dependencies: Dependencies = getDependencies();
249
- graph = await buildAppGraph(rootUri, dependencies);
250
- indexSource = (await dependencies.getSourceCode(p('app/views/pages/index.liquid'))).source;
251
- }, 15000);
252
-
253
- it('resolves function + render targets into modules/<name>/public/{lib,views/partials}', () => {
254
- const functionEdge = directRef(
255
- p('app/views/pages/index.liquid'),
256
- rangeOf(indexSource, "function items = 'modules/my_module/queries/get'"),
257
- p('modules/my_module/public/lib/queries/get.liquid'),
258
- 'function',
259
- );
260
- const renderEdge = directRef(
261
- p('app/views/pages/index.liquid'),
262
- rangeOf(indexSource, "{% render 'modules/my_module/card' %}"),
263
- p('modules/my_module/public/views/partials/card.liquid'),
264
- 'render',
265
- );
266
-
267
- expect(graph.modules[p('app/views/pages/index.liquid')].dependencies).toEqual([
268
- functionEdge,
269
- renderEdge,
270
- ]);
271
- expect(graph.modules[p('modules/my_module/public/lib/queries/get.liquid')]).toEqual(
272
- partialNode(p('modules/my_module/public/lib/queries/get.liquid'), true, [functionEdge]),
273
- );
274
- expect(graph.modules[p('modules/my_module/public/views/partials/card.liquid')]).toEqual(
275
- partialNode(p('modules/my_module/public/views/partials/card.liquid'), true, [renderEdge]),
276
- );
277
- });
278
- });
File without changes