@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.
- package/CHANGELOG.md +9 -0
- package/dist/getWebComponentMap.js +1 -1
- package/dist/getWebComponentMap.js.map +1 -1
- package/dist/graph/augment.js +0 -3
- package/dist/graph/augment.js.map +1 -1
- package/dist/graph/build.d.ts +2 -2
- package/dist/graph/build.js +11 -8
- package/dist/graph/build.js.map +1 -1
- package/dist/graph/module.d.ts +6 -9
- package/dist/graph/module.js +53 -117
- package/dist/graph/module.js.map +1 -1
- package/dist/graph/serialize.d.ts +2 -2
- package/dist/graph/serialize.js +2 -2
- package/dist/graph/serialize.js.map +1 -1
- package/dist/graph/test-helpers.d.ts +0 -13
- package/dist/graph/test-helpers.js +0 -10
- package/dist/graph/test-helpers.js.map +1 -1
- package/dist/graph/traverse.d.ts +3 -3
- package/dist/graph/traverse.js +19 -349
- package/dist/graph/traverse.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -6
- package/dist/index.js.map +1 -1
- package/dist/toSourceCode.d.ts +1 -4
- package/dist/toSourceCode.js +8 -52
- package/dist/toSourceCode.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +21 -78
- package/dist/types.js.map +1 -1
- package/dist/utils/index.d.ts +0 -3
- package/dist/utils/index.js +0 -18
- package/dist/utils/index.js.map +1 -1
- package/fixtures/skeleton/{layout/theme.liquid → app/views/layouts/application.liquid} +3 -4
- package/fixtures/skeleton/app/views/pages/index.liquid +5 -0
- package/fixtures/skeleton/app/views/partials/header.liquid +3 -0
- package/package.json +4 -4
- package/src/getWebComponentMap.ts +1 -1
- package/src/graph/augment.ts +1 -13
- package/src/graph/build.spec.ts +31 -171
- package/src/graph/build.ts +18 -14
- package/src/graph/module.ts +59 -135
- package/src/graph/serialize.spec.ts +22 -29
- package/src/graph/serialize.ts +2 -2
- package/src/graph/test-helpers.ts +1 -18
- package/src/graph/traverse.ts +28 -501
- package/src/index.ts +3 -3
- package/src/toSourceCode.ts +14 -55
- package/src/types.ts +23 -100
- package/src/utils/index.ts +0 -24
- package/fixtures/skeleton/blocks/_private.liquid +0 -1
- package/fixtures/skeleton/blocks/_static.liquid +0 -10
- package/fixtures/skeleton/blocks/group.liquid +0 -27
- package/fixtures/skeleton/blocks/render-static.liquid +0 -22
- package/fixtures/skeleton/blocks/text.liquid +0 -14
- package/fixtures/skeleton/jsconfig.json +0 -9
- package/fixtures/skeleton/sections/custom-section.liquid +0 -6
- package/fixtures/skeleton/sections/header-group.json +0 -36
- package/fixtures/skeleton/sections/header.liquid +0 -1
- package/fixtures/skeleton/templates/index.json +0 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformos/platformos-graph",
|
|
3
|
-
"version": "0.0.
|
|
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.
|
|
33
|
-
"@platformos/platformos-check-common": "0.0.
|
|
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.
|
|
39
|
+
"@platformos/platformos-check-node": "0.0.8"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/src/graph/augment.ts
CHANGED
|
@@ -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
|
}
|
package/src/graph/build.spec.ts
CHANGED
|
@@ -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 {
|
|
4
|
-
import { Dependencies,
|
|
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:
|
|
18
|
-
it('
|
|
19
|
-
const graph = await
|
|
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
|
|
24
|
-
let graph:
|
|
23
|
+
describe('with a valid app graph', () => {
|
|
24
|
+
let graph: AppGraph;
|
|
25
25
|
|
|
26
26
|
beforeEach(async () => {
|
|
27
|
-
graph = await
|
|
27
|
+
graph = await buildAppGraph(rootUri, dependencies);
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
it('
|
|
30
|
+
it('has a root URI', () => {
|
|
31
31
|
expect(graph.rootUri).toBeDefined();
|
|
32
32
|
expect(graph.rootUri).toBe(rootUri);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
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('
|
|
42
|
-
p('
|
|
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
|
|
49
|
-
const
|
|
50
|
-
assert(
|
|
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
|
-
|
|
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
|
|
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'
|
|
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
|
|
227
|
-
const
|
|
228
|
-
assert(
|
|
229
|
-
assert(
|
|
230
|
-
assert(
|
|
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
|
-
|
|
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('
|
|
242
|
-
p('
|
|
101
|
+
p('app/views/partials/parent.liquid'),
|
|
102
|
+
p('app/views/partials/header.liquid'),
|
|
243
103
|
]),
|
|
244
104
|
);
|
|
245
105
|
});
|
package/src/graph/build.ts
CHANGED
|
@@ -3,33 +3,37 @@ import {
|
|
|
3
3
|
path,
|
|
4
4
|
UriString,
|
|
5
5
|
} from '@platformos/platformos-check-common';
|
|
6
|
-
import { IDependencies,
|
|
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
|
|
11
|
+
export async function buildAppGraph(
|
|
12
12
|
rootUri: UriString,
|
|
13
13
|
ideps: IDependencies,
|
|
14
14
|
entryPoints?: UriString[],
|
|
15
|
-
): Promise<
|
|
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
|
-
//
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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:
|
|
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
|
|
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
|
|
package/src/graph/module.ts
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { path, UriString } from '@platformos/platformos-check-common';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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<
|
|
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
|
-
*
|
|
25
|
+
* AppGraph (no need for a `visited` property on modules, etc.)
|
|
31
26
|
*/
|
|
32
|
-
const ModuleCache: WeakMap<
|
|
27
|
+
const ModuleCache: WeakMap<AppGraph, Map<string, AppModule>> = new WeakMap();
|
|
33
28
|
|
|
34
|
-
export function getModule(
|
|
35
|
-
const cache = getCache(
|
|
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,
|
|
35
|
+
const relativePath = path.relative(uri, appGraph.rootUri);
|
|
41
36
|
|
|
42
37
|
switch (true) {
|
|
43
|
-
case relativePath.startsWith('assets'): {
|
|
44
|
-
return getAssetModule(
|
|
38
|
+
case relativePath.startsWith('assets') || relativePath.startsWith('modules'): {
|
|
39
|
+
return getAssetModule(appGraph, path.basename(uri));
|
|
45
40
|
}
|
|
46
41
|
|
|
47
|
-
case relativePath.
|
|
48
|
-
return
|
|
42
|
+
case relativePath.includes('views/layouts'): {
|
|
43
|
+
return getLayoutModule(appGraph, uri);
|
|
49
44
|
}
|
|
50
45
|
|
|
51
|
-
case relativePath.
|
|
52
|
-
return
|
|
46
|
+
case relativePath.includes('views/pages'): {
|
|
47
|
+
return getPageModule(appGraph, uri);
|
|
53
48
|
}
|
|
54
49
|
|
|
55
|
-
case relativePath.
|
|
56
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (!
|
|
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(
|
|
164
|
-
type,
|
|
79
|
+
return module(appGraph, {
|
|
80
|
+
type: ModuleType.Asset,
|
|
165
81
|
kind: 'unused',
|
|
166
82
|
dependencies: [],
|
|
167
83
|
references: [],
|
|
168
|
-
uri: path.join(
|
|
84
|
+
uri: path.join(appGraph.rootUri, 'assets', asset),
|
|
169
85
|
});
|
|
170
86
|
}
|
|
171
87
|
|
|
172
|
-
export function getPartialModule(
|
|
173
|
-
const uri = path.join(
|
|
174
|
-
return module(
|
|
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
|
-
|
|
185
|
-
|
|
100
|
+
appGraph: AppGraph,
|
|
101
|
+
layoutUri: string | false | undefined,
|
|
186
102
|
): LiquidModule | undefined {
|
|
187
|
-
if (
|
|
188
|
-
|
|
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:
|
|
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(
|
|
200
|
-
if (!ModuleCache.has(
|
|
201
|
-
ModuleCache.set(
|
|
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(
|
|
127
|
+
return ModuleCache.get(appGraph)!;
|
|
204
128
|
}
|
|
205
129
|
|
|
206
|
-
function module<T extends
|
|
207
|
-
const cache = getCache(
|
|
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
|
}
|