@platformos/platformos-graph 0.0.7 → 0.0.8

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 (59) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/getWebComponentMap.js +1 -1
  3. package/dist/getWebComponentMap.js.map +1 -1
  4. package/dist/graph/augment.js +0 -3
  5. package/dist/graph/augment.js.map +1 -1
  6. package/dist/graph/build.d.ts +2 -2
  7. package/dist/graph/build.js +11 -8
  8. package/dist/graph/build.js.map +1 -1
  9. package/dist/graph/module.d.ts +6 -9
  10. package/dist/graph/module.js +53 -117
  11. package/dist/graph/module.js.map +1 -1
  12. package/dist/graph/serialize.d.ts +2 -2
  13. package/dist/graph/serialize.js +2 -2
  14. package/dist/graph/serialize.js.map +1 -1
  15. package/dist/graph/test-helpers.d.ts +0 -13
  16. package/dist/graph/test-helpers.js +0 -10
  17. package/dist/graph/test-helpers.js.map +1 -1
  18. package/dist/graph/traverse.d.ts +3 -3
  19. package/dist/graph/traverse.js +19 -349
  20. package/dist/graph/traverse.js.map +1 -1
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.js +4 -6
  23. package/dist/index.js.map +1 -1
  24. package/dist/toSourceCode.d.ts +1 -4
  25. package/dist/toSourceCode.js +8 -52
  26. package/dist/toSourceCode.js.map +1 -1
  27. package/dist/tsconfig.tsbuildinfo +1 -1
  28. package/dist/types.d.ts +21 -78
  29. package/dist/types.js.map +1 -1
  30. package/dist/utils/index.d.ts +0 -3
  31. package/dist/utils/index.js +0 -18
  32. package/dist/utils/index.js.map +1 -1
  33. package/fixtures/skeleton/{layout/theme.liquid → app/views/layouts/application.liquid} +3 -4
  34. package/fixtures/skeleton/app/views/pages/index.liquid +5 -0
  35. package/fixtures/skeleton/app/views/partials/header.liquid +3 -0
  36. package/package.json +4 -4
  37. package/src/getWebComponentMap.ts +1 -1
  38. package/src/graph/augment.ts +1 -13
  39. package/src/graph/build.spec.ts +31 -171
  40. package/src/graph/build.ts +18 -14
  41. package/src/graph/module.ts +59 -135
  42. package/src/graph/serialize.spec.ts +22 -29
  43. package/src/graph/serialize.ts +2 -2
  44. package/src/graph/test-helpers.ts +1 -18
  45. package/src/graph/traverse.ts +28 -501
  46. package/src/index.ts +3 -3
  47. package/src/toSourceCode.ts +14 -55
  48. package/src/types.ts +23 -100
  49. package/src/utils/index.ts +0 -24
  50. package/fixtures/skeleton/blocks/_private.liquid +0 -1
  51. package/fixtures/skeleton/blocks/_static.liquid +0 -10
  52. package/fixtures/skeleton/blocks/group.liquid +0 -27
  53. package/fixtures/skeleton/blocks/render-static.liquid +0 -22
  54. package/fixtures/skeleton/blocks/text.liquid +0 -14
  55. package/fixtures/skeleton/jsconfig.json +0 -9
  56. package/fixtures/skeleton/sections/custom-section.liquid +0 -6
  57. package/fixtures/skeleton/sections/header-group.json +0 -36
  58. package/fixtures/skeleton/sections/header.liquid +0 -1
  59. package/fixtures/skeleton/templates/index.json +0 -20
@@ -0,0 +1,3 @@
1
+ <header>
2
+ {% render "child", children: "nav" %}
3
+ </header>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformos/platformos-graph",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Shopify Theme Graph as a data structure",
5
5
  "author": "platformOS",
6
6
  "homepage": "https://github.com/Platform-OS/platformos-tools/tree/master/packages/platformos-graph#readme",
@@ -29,13 +29,13 @@
29
29
  "type-check": "tsc --noEmit"
30
30
  },
31
31
  "dependencies": {
32
- "@platformos/liquid-html-parser": "^0.0.7",
33
- "@platformos/platformos-check-common": "0.0.7",
32
+ "@platformos/liquid-html-parser": "^0.0.8",
33
+ "@platformos/platformos-check-common": "0.0.8",
34
34
  "acorn": "^8.16.0",
35
35
  "acorn-walk": "^8.3.5",
36
36
  "vscode-uri": "^3.1.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@platformos/platformos-check-node": "0.0.7"
39
+ "@platformos/platformos-check-node": "0.0.8"
40
40
  }
41
41
  }
@@ -46,7 +46,7 @@ export async function findWebComponentReferences(
46
46
  result: WebComponentMap,
47
47
  ): Promise<Void> {
48
48
  const sourceCode = await getSourceCode(uri);
49
- if (sourceCode.type !== 'javascript') {
49
+ if (!uri.endsWith('.js')) {
50
50
  return;
51
51
  }
52
52
 
@@ -1,9 +1,4 @@
1
- import {
2
- memoize,
3
- memo,
4
- recursiveReadDirectory as findAllFiles,
5
- path,
6
- } from '@platformos/platformos-check-common';
1
+ import { memoize, path } from '@platformos/platformos-check-common';
7
2
  import { toSourceCode } from '../toSourceCode';
8
3
  import { AugmentedDependencies, IDependencies } from '../types';
9
4
  import { identity } from '../utils';
@@ -11,8 +6,6 @@ import { identity } from '../utils';
11
6
  export function augmentDependencies(rootUri: string, ideps: IDependencies): AugmentedDependencies {
12
7
  return {
13
8
  fs: ideps.fs,
14
- getBlockSchema: memoize(ideps.getBlockSchema, identity),
15
- getSectionSchema: memoize(ideps.getSectionSchema, identity),
16
9
 
17
10
  // parse at most once
18
11
  getSourceCode: memoize(
@@ -25,10 +18,5 @@ export function augmentDependencies(rootUri: string, ideps: IDependencies): Augm
25
18
  ),
26
19
 
27
20
  getWebComponentDefinitionReference: ideps.getWebComponentDefinitionReference,
28
- getThemeBlockNames: memo(() =>
29
- findAllFiles(ideps.fs, path.join(rootUri, 'blocks'), ([uri]) => uri.endsWith('.liquid')).then(
30
- (uris) => uris.map((uri) => path.basename(uri, '.liquid')),
31
- ),
32
- ),
33
21
  };
34
22
  }
@@ -1,7 +1,7 @@
1
1
  import { path as pathUtils, SourceCodeType } from '@platformos/platformos-check-common';
2
2
  import { assert, beforeAll, beforeEach, describe, expect, it } from 'vitest';
3
- import { buildThemeGraph } from '../index';
4
- import { Dependencies, JsonModuleKind, LiquidModuleKind, ModuleType, ThemeGraph } from '../types';
3
+ import { buildAppGraph } from '../index';
4
+ import { Dependencies, LiquidModuleKind, ModuleType, AppGraph } from '../types';
5
5
  import { getDependencies, skeleton } from './test-helpers';
6
6
 
7
7
  describe('Module: index', () => {
@@ -14,162 +14,51 @@ describe('Module: index', () => {
14
14
  dependencies = await getDependencies(rootUri);
15
15
  }, 15000);
16
16
 
17
- describe('Unit: buildThemeGraph', { timeout: 10000 }, () => {
18
- it('build a graph of the theme', { timeout: 10000 }, async () => {
19
- const graph = await buildThemeGraph(rootUri, dependencies);
17
+ describe('Unit: buildAppGraph', { timeout: 10000 }, () => {
18
+ it('builds a graph of the app', { timeout: 10000 }, async () => {
19
+ const graph = await buildAppGraph(rootUri, dependencies);
20
20
  expect(graph).toBeDefined();
21
21
  });
22
22
 
23
- describe('with a valid theme graph', () => {
24
- let graph: ThemeGraph;
23
+ describe('with a valid app graph', () => {
24
+ let graph: AppGraph;
25
25
 
26
26
  beforeEach(async () => {
27
- graph = await buildThemeGraph(rootUri, dependencies);
27
+ graph = await buildAppGraph(rootUri, dependencies);
28
28
  });
29
29
 
30
- it('have a root URI', () => {
30
+ it('has a root URI', () => {
31
31
  expect(graph.rootUri).toBeDefined();
32
32
  expect(graph.rootUri).toBe(rootUri);
33
33
  });
34
34
 
35
- // We're using sections as entry points because the section rendering API can render
36
- // any section without it needing a preset or default value in its schema.
37
- it('infers entry points from the templates folder and section files', () => {
38
- expect(graph.entryPoints).toHaveLength(3);
35
+ it('infers entry points from layouts and pages', () => {
36
+ expect(graph.entryPoints).toHaveLength(2);
39
37
  expect(graph.entryPoints.map((x) => x.uri)).toEqual(
40
38
  expect.arrayContaining([
41
- p('templates/index.json'),
42
- p('sections/custom-section.liquid'),
43
- p('sections/header.liquid'),
39
+ p('app/views/layouts/application.liquid'),
40
+ p('app/views/pages/index.liquid'),
44
41
  ]),
45
42
  );
46
43
  });
47
44
 
48
- it("finds layout/theme.liquid's dependencies and references", () => {
49
- const themeLayout = graph.modules[p('layout/theme.liquid')];
50
- assert(themeLayout);
45
+ it("finds app/views/layouts/application.liquid's dependencies", () => {
46
+ const layout = graph.modules[p('app/views/layouts/application.liquid')];
47
+ assert(layout);
48
+ assert(layout.type === ModuleType.Liquid);
49
+ assert(layout.kind === LiquidModuleKind.Layout);
51
50
 
52
- // outgoing links
53
- const deps = themeLayout.dependencies;
54
- assert(deps.map((x) => x.source.uri).every((x) => x === p('layout/theme.liquid')));
51
+ const deps = layout.dependencies;
55
52
  expect(deps.map((x) => x.target.uri)).toEqual(
56
53
  expect.arrayContaining([
57
- p('sections/header-group.json'),
58
54
  p('assets/theme.js'),
59
55
  p('assets/theme.css'),
56
+ p('app/views/partials/header.liquid'),
60
57
  ]),
61
58
  );
62
-
63
- // ingoing links
64
- const refs = themeLayout.references;
65
- expect(refs).toHaveLength(1);
66
- assert(refs.map((x) => x.target.uri).every((x) => x === p('layout/theme.liquid')));
67
- expect(refs.map((x) => x.source.uri)).toEqual(
68
- expect.arrayContaining([p('templates/index.json')]),
69
- );
70
- });
71
-
72
- it("finds templates/index.json's dependencies and references", () => {
73
- const indexTemplate = graph.modules[p('templates/index.json')];
74
- assert(indexTemplate);
75
- assert(indexTemplate.type === ModuleType.Json);
76
- assert(indexTemplate.kind === JsonModuleKind.Template);
77
-
78
- // outgoing links
79
- const deps = indexTemplate.dependencies;
80
- assert(deps.map((x) => x.source.uri).every((x) => x === p('templates/index.json')));
81
- expect(deps.map((x) => x.target.uri)).toEqual(
82
- expect.arrayContaining([
83
- p('layout/theme.liquid'),
84
- p('sections/custom-section.liquid'),
85
- p('blocks/group.liquid'),
86
- p('blocks/text.liquid'),
87
- ]),
88
- );
89
-
90
- // ingoing links
91
- const refs = indexTemplate.references;
92
- expect(refs).toHaveLength(0);
93
- });
94
-
95
- it("finds sections/custom-section's dependencies and references", () => {
96
- const customSection = graph.modules[p('sections/custom-section.liquid')];
97
- assert(customSection);
98
- assert(customSection.type === ModuleType.Liquid);
99
- assert(customSection.kind === LiquidModuleKind.Section);
100
-
101
- // outgoing links
102
- const deps = customSection.dependencies;
103
- assert(deps.map((x) => x.source.uri).every((x) => x === customSection.uri));
104
- expect(deps.map((x) => x.target.uri)).toEqual(
105
- expect.arrayContaining([
106
- p('blocks/group.liquid'),
107
- p('blocks/text.liquid'),
108
- p('blocks/_private.liquid'),
109
- ]),
110
- );
111
-
112
- // ingoing links
113
- const refs = customSection.references;
114
- assert(refs.map((x) => x.target.uri).every((x) => x === customSection.uri));
115
- expect(refs.map((x) => x.source.uri)).toEqual(
116
- expect.arrayContaining([p('templates/index.json'), p('sections/header-group.json')]),
117
- );
118
- expect(refs).toHaveLength(2);
119
- });
120
-
121
- it("finds blocks/group's dependencies and references", () => {
122
- const groupBlock = graph.modules[p('blocks/group.liquid')];
123
- assert(groupBlock);
124
- assert(groupBlock.type === ModuleType.Liquid);
125
- assert(groupBlock.kind === LiquidModuleKind.Block);
126
-
127
- const deps = groupBlock.dependencies;
128
- assert(deps.map((x) => x.source.uri).every((x) => x === groupBlock.uri));
129
- expect(deps).toEqual(
130
- expect.arrayContaining([
131
- {
132
- source: loc('blocks/group.liquid'),
133
- target: loc('app/views/partials/parent.liquid'),
134
- type: 'direct',
135
- }, // direct dep in partial
136
- {
137
- source: loc('blocks/group.liquid'),
138
- target: loc('blocks/text.liquid'),
139
- type: 'indirect',
140
- }, // indirect because of @theme
141
- {
142
- source: loc('blocks/group.liquid'),
143
- target: loc('blocks/text.liquid'),
144
- type: 'preset',
145
- }, // direct dep in preset
146
- ]),
147
- );
148
-
149
- const refs = groupBlock.references;
150
- assert(refs.map((x) => x.target.uri).every((x) => x === groupBlock.uri));
151
- expect(refs.map((x) => x.source.uri)).toEqual(
152
- expect.arrayContaining([
153
- p('templates/index.json'),
154
- p('sections/custom-section.liquid'), // @theme ref
155
- p('sections/header-group.json'), // custom-section > group
156
- p('blocks/group.liquid'), // @theme ref
157
- ]),
158
- );
159
-
160
- expect(refs).toContainEqual(
161
- // Expecting the `@theme` reference in the custom-section schema to be indirect
162
- expect.objectContaining({
163
- type: 'indirect',
164
- source: {
165
- uri: p('sections/custom-section.liquid'),
166
- range: [expect.any(Number), expect.any(Number)],
167
- },
168
- }),
169
- );
170
59
  });
171
60
 
172
- it("finds the app/views/partials/parent's dependencies and references", async () => {
61
+ it("finds app/views/partials/parent's dependencies and references", async () => {
173
62
  const parentPartial = graph.modules[p('app/views/partials/parent.liquid')];
174
63
  assert(parentPartial);
175
64
  assert(parentPartial.type === ModuleType.Liquid);
@@ -179,22 +68,10 @@ describe('Module: index', () => {
179
68
  const deps = parentPartial.dependencies;
180
69
  assert(deps.map((x) => x.source.uri).every((x) => x === parentPartial.uri));
181
70
  expect(deps.map((x) => x.target.uri)).toEqual(
182
- expect.arrayContaining([
183
- p('app/views/partials/child.liquid'), // {% render 'child' %}
184
- p('assets/theme.js'), // <parent-element>
185
- ]),
186
- );
187
-
188
- // ingoing links
189
- const refs = parentPartial.references;
190
- assert(refs.map((x) => x.target.uri).every((x) => x === parentPartial.uri));
191
- expect(refs.map((x) => x.source.uri)).toEqual(
192
- expect.arrayContaining([
193
- p('blocks/group.liquid'), // {% render 'parent' %}
194
- ]),
71
+ expect.arrayContaining([p('app/views/partials/child.liquid'), p('assets/theme.js')]),
195
72
  );
196
73
 
197
- // {% render 'child', children: children %} dependency
74
+ // {% render 'child' %} dependency
198
75
  const parentSource = await dependencies.getSourceCode(
199
76
  p('app/views/partials/parent.liquid'),
200
77
  );
@@ -210,36 +87,19 @@ describe('Module: index', () => {
210
87
  ],
211
88
  }),
212
89
  );
213
-
214
- // <parent-element> dependency
215
- expect(parentPartial.dependencies.map((x) => x.source)).toContainEqual(
216
- expect.objectContaining({
217
- uri: p('app/views/partials/parent.liquid'),
218
- range: [
219
- parentSource.source.indexOf('<parent-element'),
220
- parentSource.source.indexOf('<parent-element') + '<parent-element'.length,
221
- ],
222
- }),
223
- );
224
90
  });
225
91
 
226
- it("finds the blocks/_static's dependencies and references", () => {
227
- const staticBlock = graph.modules[p('blocks/_static.liquid')];
228
- assert(staticBlock);
229
- assert(staticBlock.type === ModuleType.Liquid);
230
- assert(staticBlock.kind === LiquidModuleKind.Block);
231
-
232
- // outgoing links
233
- const deps = staticBlock.dependencies;
234
- expect(deps).toEqual([]);
92
+ it("finds app/views/partials/child's references", () => {
93
+ const childPartial = graph.modules[p('app/views/partials/child.liquid')];
94
+ assert(childPartial);
95
+ assert(childPartial.type === ModuleType.Liquid);
96
+ assert(childPartial.kind === LiquidModuleKind.Partial);
235
97
 
236
- // ingoing links
237
- const refs = staticBlock.references;
238
- assert(refs.map((x) => x.target.uri).every((x) => x === staticBlock.uri));
98
+ const refs = childPartial.references;
239
99
  expect(refs.map((x) => x.source.uri)).toEqual(
240
100
  expect.arrayContaining([
241
- p('sections/header-group.json'),
242
- p('blocks/render-static.liquid'),
101
+ p('app/views/partials/parent.liquid'),
102
+ p('app/views/partials/header.liquid'),
243
103
  ]),
244
104
  );
245
105
  });
@@ -3,33 +3,37 @@ import {
3
3
  path,
4
4
  UriString,
5
5
  } from '@platformos/platformos-check-common';
6
- import { IDependencies, ThemeGraph, ThemeModule } from '../types';
6
+ import { IDependencies, AppGraph, AppModule } from '../types';
7
7
  import { augmentDependencies } from './augment';
8
8
  import { getModule } from './module';
9
9
  import { traverseModule } from './traverse';
10
10
 
11
- export async function buildThemeGraph(
11
+ export async function buildAppGraph(
12
12
  rootUri: UriString,
13
13
  ideps: IDependencies,
14
14
  entryPoints?: UriString[],
15
- ): Promise<ThemeGraph> {
15
+ ): Promise<AppGraph> {
16
16
  const deps = augmentDependencies(rootUri, ideps);
17
17
 
18
18
  entryPoints =
19
19
  entryPoints ??
20
20
  (await findAllFiles(deps.fs, rootUri, ([uri]) => {
21
- // Templates are entry points in the theme graph.
22
- const isTemplateFile = uri.startsWith(path.join(rootUri, 'templates'));
23
-
24
- // Since any section file can be rendered directly by the Section Rendering API,
25
- // we consider all section files as entry points.
26
- const isSectionFile =
27
- uri.startsWith(path.join(rootUri, 'sections')) && uri.endsWith('.liquid');
28
-
29
- return isTemplateFile || isSectionFile;
21
+ // Layouts are entry points they wrap all page content.
22
+ const isLayoutFile =
23
+ (uri.startsWith(path.join(rootUri, 'app/views/layouts')) ||
24
+ uri.startsWith(path.join(rootUri, 'views/layouts'))) &&
25
+ uri.endsWith('.liquid');
26
+
27
+ // Pages are also entry points — they are directly requested.
28
+ const isPageFile =
29
+ (uri.startsWith(path.join(rootUri, 'app/views/pages')) ||
30
+ uri.startsWith(path.join(rootUri, 'views/pages'))) &&
31
+ uri.endsWith('.liquid');
32
+
33
+ return isLayoutFile || isPageFile;
30
34
  }));
31
35
 
32
- const graph: ThemeGraph = {
36
+ const graph: AppGraph = {
33
37
  entryPoints: [],
34
38
  modules: {},
35
39
  rootUri,
@@ -37,7 +41,7 @@ export async function buildThemeGraph(
37
41
 
38
42
  graph.entryPoints = entryPoints
39
43
  .map((uri) => getModule(graph, uri))
40
- .filter((x): x is ThemeModule => x !== undefined);
44
+ .filter((x): x is AppModule => x !== undefined);
41
45
 
42
46
  await Promise.all(graph.entryPoints.map((entry) => traverseModule(entry, graph, deps)));
43
47
 
@@ -1,17 +1,12 @@
1
1
  import { path, UriString } from '@platformos/platformos-check-common';
2
2
  import {
3
- CssModule,
4
- ImageModule,
5
- JavaScriptModule,
6
- JsonModule,
7
- JsonModuleKind,
3
+ AssetModule,
4
+ AppGraph,
5
+ AppModule,
8
6
  LiquidModule,
9
7
  LiquidModuleKind,
10
8
  ModuleType,
11
9
  SUPPORTED_ASSET_IMAGE_EXTENSIONS,
12
- SvgModule,
13
- ThemeGraph,
14
- ThemeModule,
15
10
  } from '../types';
16
11
  import { extname } from '../utils';
17
12
 
@@ -23,155 +18,76 @@ import { extname } from '../utils';
23
18
  * graphs' modules record), we want to avoid creating two different module objects
24
19
  * that represent the same file.
25
20
  *
26
- * We're using a WeakMap<ThemeGraph> to cache modules so that if the theme graph
21
+ * We're using a WeakMap<AppGraph> to cache modules so that if the app graph
27
22
  * gets garbage collected, the module cache will also be garbage collected.
28
23
  *
29
24
  * This allows us to have a module cache without changing the API of the
30
- * ThemeGraph (no need for a `visited` property on modules, etc.)
25
+ * AppGraph (no need for a `visited` property on modules, etc.)
31
26
  */
32
- const ModuleCache: WeakMap<ThemeGraph, Map<string, ThemeModule>> = new WeakMap();
27
+ const ModuleCache: WeakMap<AppGraph, Map<string, AppModule>> = new WeakMap();
33
28
 
34
- export function getModule(themeGraph: ThemeGraph, uri: UriString): ThemeModule | undefined {
35
- const cache = getCache(themeGraph);
29
+ export function getModule(appGraph: AppGraph, uri: UriString): AppModule | undefined {
30
+ const cache = getCache(appGraph);
36
31
  if (cache.has(uri)) {
37
32
  return cache.get(uri)!;
38
33
  }
39
34
 
40
- const relativePath = path.relative(uri, themeGraph.rootUri);
35
+ const relativePath = path.relative(uri, appGraph.rootUri);
41
36
 
42
37
  switch (true) {
43
- case relativePath.startsWith('assets'): {
44
- return getAssetModule(themeGraph, path.basename(uri));
38
+ case relativePath.startsWith('assets') || relativePath.startsWith('modules'): {
39
+ return getAssetModule(appGraph, path.basename(uri));
45
40
  }
46
41
 
47
- case relativePath.startsWith('blocks'): {
48
- return getThemeBlockModule(themeGraph, path.basename(uri, '.liquid'));
42
+ case relativePath.includes('views/layouts'): {
43
+ return getLayoutModule(appGraph, uri);
49
44
  }
50
45
 
51
- case relativePath.startsWith('layout'): {
52
- return getLayoutModule(themeGraph, path.basename(uri, '.liquid'));
46
+ case relativePath.includes('views/pages'): {
47
+ return getPageModule(appGraph, uri);
53
48
  }
54
49
 
55
- case relativePath.startsWith('sections'): {
56
- if (relativePath.endsWith('.json')) {
57
- return getSectionGroupModule(themeGraph, path.basename(uri, '.json'));
58
- }
59
- return getSectionModule(themeGraph, path.basename(uri, '.liquid'));
60
- }
61
-
62
- case relativePath.includes('/views/partials') || relativePath.includes('/lib/'): {
63
- return getPartialModule(themeGraph, path.basename(uri, '.liquid'));
50
+ case relativePath.includes('views/partials') || relativePath.includes('/lib/'): {
51
+ return getPartialModule(appGraph, path.basename(uri, '.liquid'));
64
52
  }
65
53
 
66
54
  case relativePath.startsWith('snippets'): {
67
- return getPartialModule(themeGraph, path.basename(uri, '.liquid'));
68
- }
69
-
70
- case relativePath.startsWith('templates'): {
71
- return getTemplateModule(themeGraph, uri);
72
- }
73
- }
74
- }
75
-
76
- export function getTemplateModule(themeGraph: ThemeGraph, uri: UriString): ThemeModule {
77
- const extension = extname(uri);
78
- switch (extension) {
79
- case 'json': {
80
- return module(themeGraph, {
81
- type: ModuleType.Json,
82
- kind: JsonModuleKind.Template,
83
- dependencies: [],
84
- references: [],
85
- uri: uri,
86
- });
87
- }
88
-
89
- case 'liquid': {
90
- return module(themeGraph, {
91
- type: ModuleType.Liquid,
92
- kind: LiquidModuleKind.Template,
93
- dependencies: [],
94
- references: [],
95
- uri: uri,
96
- });
97
- }
98
-
99
- default: {
100
- throw new Error(`Unknown template type for ${uri}`);
55
+ return getPartialModule(appGraph, path.basename(uri, '.liquid'));
101
56
  }
102
57
  }
103
58
  }
104
59
 
105
- export function getThemeBlockModule(themeGraph: ThemeGraph, blockType: string): LiquidModule {
106
- const uri = path.join(themeGraph.rootUri, 'blocks', `${blockType}.liquid`);
107
- return module(themeGraph, {
108
- type: ModuleType.Liquid,
109
- kind: LiquidModuleKind.Block,
110
- dependencies: [],
111
- references: [],
112
- uri,
113
- });
114
- }
115
-
116
- export function getSectionModule(themeGraph: ThemeGraph, sectionType: string): LiquidModule {
117
- const uri = path.join(themeGraph.rootUri, 'sections', `${sectionType}.liquid`);
118
- return module(themeGraph, {
119
- type: ModuleType.Liquid,
120
- kind: LiquidModuleKind.Section,
121
- dependencies: [],
122
- references: [],
123
- uri,
124
- });
125
- }
126
-
127
- export function getSectionGroupModule(
128
- themeGraph: ThemeGraph,
129
- sectionGroupType: string,
130
- ): JsonModule {
131
- const uri = path.join(themeGraph.rootUri, 'sections', `${sectionGroupType}.json`);
132
- return module(themeGraph, {
133
- type: ModuleType.Json,
134
- kind: JsonModuleKind.SectionGroup,
135
- dependencies: [],
136
- references: [],
137
- uri,
138
- });
139
- }
140
-
141
- export function getAssetModule(
142
- themeGraph: ThemeGraph,
143
- asset: string,
144
- ): JavaScriptModule | CssModule | SvgModule | ImageModule | undefined {
60
+ export function getAssetModule(appGraph: AppGraph, asset: string): AssetModule | undefined {
145
61
  const extension = extname(asset);
146
62
 
147
- let type: ModuleType | undefined = undefined;
148
-
149
- if (SUPPORTED_ASSET_IMAGE_EXTENSIONS.includes(extension)) {
150
- type = ModuleType.Image;
151
- } else if (extension === 'js') {
152
- type = ModuleType.JavaScript;
153
- } else if (extension === 'css') {
154
- type = ModuleType.Css;
155
- } else if (extension === 'svg') {
156
- type = ModuleType.Svg;
157
- }
158
-
159
- if (!type) {
63
+ const SUPPORTED_ASSET_EXTENSIONS = [
64
+ ...SUPPORTED_ASSET_IMAGE_EXTENSIONS,
65
+ 'js',
66
+ 'css',
67
+ 'svg',
68
+ 'pdf',
69
+ 'woff',
70
+ 'woff2',
71
+ 'ttf',
72
+ 'eot',
73
+ ];
74
+
75
+ if (!SUPPORTED_ASSET_EXTENSIONS.includes(extension)) {
160
76
  return undefined;
161
77
  }
162
78
 
163
- return module(themeGraph, {
164
- type,
79
+ return module(appGraph, {
80
+ type: ModuleType.Asset,
165
81
  kind: 'unused',
166
82
  dependencies: [],
167
83
  references: [],
168
- uri: path.join(themeGraph.rootUri, 'assets', asset),
84
+ uri: path.join(appGraph.rootUri, 'assets', asset),
169
85
  });
170
86
  }
171
87
 
172
- export function getPartialModule(themeGraph: ThemeGraph, partial: string): LiquidModule {
173
- const uri = path.join(themeGraph.rootUri, 'app/views/partials', `${partial}.liquid`);
174
- return module(themeGraph, {
88
+ export function getPartialModule(appGraph: AppGraph, partial: string): LiquidModule {
89
+ const uri = path.join(appGraph.rootUri, 'app/views/partials', `${partial}.liquid`);
90
+ return module(appGraph, {
175
91
  type: ModuleType.Liquid,
176
92
  kind: LiquidModuleKind.Partial,
177
93
  uri: uri,
@@ -181,30 +97,38 @@ export function getPartialModule(themeGraph: ThemeGraph, partial: string): Liqui
181
97
  }
182
98
 
183
99
  export function getLayoutModule(
184
- themeGraph: ThemeGraph,
185
- layoutName: string | false | undefined = 'theme',
100
+ appGraph: AppGraph,
101
+ layoutUri: string | false | undefined,
186
102
  ): LiquidModule | undefined {
187
- if (layoutName === false) return undefined;
188
- if (layoutName === undefined) layoutName = 'theme';
189
- const uri = path.join(themeGraph.rootUri, 'layout', `${layoutName}.liquid`);
190
- return module(themeGraph, {
103
+ if (!layoutUri) return undefined;
104
+ return module(appGraph, {
191
105
  type: ModuleType.Liquid,
192
106
  kind: LiquidModuleKind.Layout,
193
- uri: uri,
107
+ uri: layoutUri,
108
+ dependencies: [],
109
+ references: [],
110
+ });
111
+ }
112
+
113
+ export function getPageModule(appGraph: AppGraph, pageUri: string): LiquidModule {
114
+ return module(appGraph, {
115
+ type: ModuleType.Liquid,
116
+ kind: LiquidModuleKind.Page,
117
+ uri: pageUri,
194
118
  dependencies: [],
195
119
  references: [],
196
120
  });
197
121
  }
198
122
 
199
- function getCache(themeGraph: ThemeGraph): Map<string, ThemeModule> {
200
- if (!ModuleCache.has(themeGraph)) {
201
- ModuleCache.set(themeGraph, new Map());
123
+ function getCache(appGraph: AppGraph): Map<string, AppModule> {
124
+ if (!ModuleCache.has(appGraph)) {
125
+ ModuleCache.set(appGraph, new Map());
202
126
  }
203
- return ModuleCache.get(themeGraph)!;
127
+ return ModuleCache.get(appGraph)!;
204
128
  }
205
129
 
206
- function module<T extends ThemeModule>(themeGraph: ThemeGraph, mod: T): T {
207
- const cache = getCache(themeGraph);
130
+ function module<T extends AppModule>(appGraph: AppGraph, mod: T): T {
131
+ const cache = getCache(appGraph);
208
132
  if (!cache.has(mod.uri)) {
209
133
  cache.set(mod.uri, mod);
210
134
  }