@prismicio/adapter-sveltekit 0.0.1

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 (61) hide show
  1. package/dist/constants.d.ts +4 -0
  2. package/dist/constants.js +5 -0
  3. package/dist/constants.js.map +1 -0
  4. package/dist/hooks/project-init.d.ts +3 -0
  5. package/dist/hooks/project-init.js +195 -0
  6. package/dist/hooks/project-init.js.map +1 -0
  7. package/dist/hooks/project-init.templates.d.ts +9 -0
  8. package/dist/hooks/project-init.templates.js +171 -0
  9. package/dist/hooks/project-init.templates.js.map +1 -0
  10. package/dist/hooks/slice-create.d.ts +3 -0
  11. package/dist/hooks/slice-create.js +53 -0
  12. package/dist/hooks/slice-create.js.map +1 -0
  13. package/dist/hooks/slice-create.templates.d.ts +6 -0
  14. package/dist/hooks/slice-create.templates.js +40 -0
  15. package/dist/hooks/slice-create.templates.js.map +1 -0
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.js +5 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/lib/checkIsTypeScriptProject.d.ts +8 -0
  20. package/dist/lib/checkIsTypeScriptProject.js +8 -0
  21. package/dist/lib/checkIsTypeScriptProject.js.map +1 -0
  22. package/dist/lib/getJSFileExtension.d.ts +5 -0
  23. package/dist/lib/getJSFileExtension.js +12 -0
  24. package/dist/lib/getJSFileExtension.js.map +1 -0
  25. package/dist/lib/getSvelteMajor.d.ts +1 -0
  26. package/dist/lib/getSvelteMajor.js +16 -0
  27. package/dist/lib/getSvelteMajor.js.map +1 -0
  28. package/dist/lib/pascalCase.d.ts +8 -0
  29. package/dist/lib/pascalCase.js +8 -0
  30. package/dist/lib/pascalCase.js.map +1 -0
  31. package/dist/lib/rejectIfNecessary.d.ts +1 -0
  32. package/dist/lib/rejectIfNecessary.js +10 -0
  33. package/dist/lib/rejectIfNecessary.js.map +1 -0
  34. package/dist/lib/requireResolve.d.ts +10 -0
  35. package/dist/lib/requireResolve.js +16 -0
  36. package/dist/lib/requireResolve.js.map +1 -0
  37. package/dist/lib/upsertSliceLibraryIndexFile.d.ts +7 -0
  38. package/dist/lib/upsertSliceLibraryIndexFile.js +50 -0
  39. package/dist/lib/upsertSliceLibraryIndexFile.js.map +1 -0
  40. package/dist/package.json.js +5 -0
  41. package/dist/package.json.js.map +1 -0
  42. package/dist/plugin.d.ts +2 -0
  43. package/dist/plugin.js +144 -0
  44. package/dist/plugin.js.map +1 -0
  45. package/dist/types.d.ts +28 -0
  46. package/package.json +95 -0
  47. package/src/constants.ts +5 -0
  48. package/src/hooks/project-init.templates.ts +173 -0
  49. package/src/hooks/project-init.ts +315 -0
  50. package/src/hooks/slice-create.templates.ts +82 -0
  51. package/src/hooks/slice-create.ts +84 -0
  52. package/src/index.ts +3 -0
  53. package/src/lib/checkIsTypeScriptProject.ts +18 -0
  54. package/src/lib/getJSFileExtension.ts +22 -0
  55. package/src/lib/getSvelteMajor.ts +23 -0
  56. package/src/lib/pascalCase.ts +12 -0
  57. package/src/lib/rejectIfNecessary.ts +16 -0
  58. package/src/lib/requireResolve.ts +30 -0
  59. package/src/lib/upsertSliceLibraryIndexFile.ts +78 -0
  60. package/src/plugin.ts +190 -0
  61. package/src/types.ts +31 -0
@@ -0,0 +1,315 @@
1
+ import * as path from "node:path";
2
+
3
+ import type {
4
+ ProjectInitHook,
5
+ ProjectInitHookData,
6
+ PluginSystemContext,
7
+ } from "@prismicio/plugin-kit";
8
+ import {
9
+ checkHasProjectFile,
10
+ writeProjectFile,
11
+ } from "@prismicio/plugin-kit/fs";
12
+ import { source } from "common-tags";
13
+ import { loadFile } from "magicast";
14
+
15
+ import { checkIsTypeScriptProject } from "../lib/checkIsTypeScriptProject";
16
+ import { getJSFileExtension } from "../lib/getJSFileExtension";
17
+ import { getSvelteMajor } from "../lib/getSvelteMajor";
18
+ import { rejectIfNecessary } from "../lib/rejectIfNecessary";
19
+ import { upsertSliceLibraryIndexFile } from "../lib/upsertSliceLibraryIndexFile";
20
+ import type { PluginOptions } from "../types";
21
+
22
+ import {
23
+ previewAPIRouteTemplate,
24
+ prismicIOFileTemplate,
25
+ rootLayoutTemplate,
26
+ } from "./project-init.templates";
27
+
28
+ type InstallDependenciesArgs = {
29
+ installDependencies: ProjectInitHookData["installDependencies"];
30
+ };
31
+
32
+ const installDependencies = async ({
33
+ installDependencies,
34
+ }: InstallDependenciesArgs) => {
35
+ await installDependencies({
36
+ dependencies: {
37
+ "@prismicio/client": "latest",
38
+ "@prismicio/svelte": "latest",
39
+ },
40
+ });
41
+ };
42
+
43
+ type CreatePrismicIOFileArgs = PluginSystemContext<PluginOptions>;
44
+
45
+ const createPrismicIOFile = async ({
46
+ helpers,
47
+ options,
48
+ }: CreatePrismicIOFileArgs) => {
49
+ const extension = await getJSFileExtension({ helpers, options });
50
+ const filename = path.join(`src/lib/prismicio.${extension}`);
51
+
52
+ if (await checkHasProjectFile({ filename, helpers })) {
53
+ return;
54
+ }
55
+
56
+ const typescript = await checkIsTypeScriptProject({ helpers, options });
57
+ const contents = prismicIOFileTemplate({ typescript });
58
+
59
+ await writeProjectFile({
60
+ filename,
61
+ contents,
62
+ format: options.format,
63
+ helpers,
64
+ });
65
+ };
66
+
67
+ const createPreviewRouteMatcherFile = async ({
68
+ helpers,
69
+ options,
70
+ }: PluginSystemContext<PluginOptions>) => {
71
+ const extension = await getJSFileExtension({ helpers, options });
72
+ const filename = path.join(`src/params/preview.${extension}`);
73
+
74
+ if (await checkHasProjectFile({ filename, helpers })) {
75
+ return;
76
+ }
77
+
78
+ const contents = source`
79
+ export function match(param) {
80
+ return param === 'preview';
81
+ }
82
+ `;
83
+
84
+ await writeProjectFile({
85
+ filename,
86
+ contents,
87
+ format: options.format,
88
+ helpers,
89
+ });
90
+ };
91
+
92
+ const createPreviewAPIRoute = async ({
93
+ helpers,
94
+ options,
95
+ }: PluginSystemContext<PluginOptions>) => {
96
+ const extension = await getJSFileExtension({ helpers, options });
97
+ const filename = path.join(
98
+ "src",
99
+ "routes",
100
+ "api",
101
+ "preview",
102
+ `+server.${extension}`,
103
+ );
104
+
105
+ if (await checkHasProjectFile({ filename, helpers })) {
106
+ return;
107
+ }
108
+
109
+ const typescript = await checkIsTypeScriptProject({ helpers, options });
110
+ const contents = previewAPIRouteTemplate({ typescript });
111
+
112
+ await writeProjectFile({
113
+ filename,
114
+ contents,
115
+ format: options.format,
116
+ helpers,
117
+ });
118
+ };
119
+
120
+ const createPreviewRouteDirectory = async ({
121
+ helpers,
122
+ options,
123
+ }: PluginSystemContext<PluginOptions>) => {
124
+ const filename = path.join(
125
+ "src",
126
+ "routes",
127
+ "[[preview=preview]]",
128
+ "README.md",
129
+ );
130
+
131
+ if (await checkHasProjectFile({ filename, helpers })) {
132
+ return;
133
+ }
134
+
135
+ const contents = source`
136
+ This directory adds support for optional \`/preview\` routes. Do not remove this directory.
137
+
138
+ All routes within this directory will be served using the following URLs:
139
+
140
+ - \`/example-route\` (prerendered)
141
+ - \`/preview/example-route\` (server-rendered)
142
+
143
+ See <https://prismic.io/docs/svelte-preview> for more information.
144
+ `;
145
+
146
+ await writeProjectFile({
147
+ filename,
148
+ contents,
149
+ format: options.format,
150
+ helpers,
151
+ });
152
+ };
153
+
154
+ const createRootLayoutServerFile = async ({
155
+ helpers,
156
+ options,
157
+ }: PluginSystemContext<PluginOptions>) => {
158
+ const extension = await getJSFileExtension({ helpers, options });
159
+ const filename = path.join(`src/routes/+layout.server.${extension}`);
160
+
161
+ if (await checkHasProjectFile({ filename, helpers })) {
162
+ return;
163
+ }
164
+
165
+ const contents = source`
166
+ export const prerender = "auto";
167
+ `;
168
+
169
+ await writeProjectFile({
170
+ filename,
171
+ contents,
172
+ format: options.format,
173
+ helpers,
174
+ });
175
+ };
176
+
177
+ const createRootLayoutFile = async ({
178
+ helpers,
179
+ options,
180
+ }: PluginSystemContext<PluginOptions>) => {
181
+ const filename = path.join("src", "routes", "+layout.svelte");
182
+
183
+ if (await checkHasProjectFile({ filename, helpers })) {
184
+ return;
185
+ }
186
+
187
+ const contents = rootLayoutTemplate({ version: await getSvelteMajor() });
188
+
189
+ await writeProjectFile({
190
+ filename,
191
+ contents,
192
+ format: options.format,
193
+ formatOptions: {
194
+ prettier: {
195
+ plugins: ["prettier-plugin-svelte"],
196
+ parser: "svelte",
197
+ },
198
+ },
199
+ helpers,
200
+ });
201
+ };
202
+
203
+ const modifyPrismicConfig = async ({
204
+ helpers,
205
+ options,
206
+ actions,
207
+ }: PluginSystemContext<PluginOptions>) => {
208
+ const project = await helpers.getProject();
209
+
210
+ // Nest the default Slice Library in the src directory if it exists and
211
+ // is empty.
212
+ if (
213
+ (await checkHasProjectFile({
214
+ filename: "./src/lib",
215
+ helpers,
216
+ })) &&
217
+ project.config.libraries &&
218
+ JSON.stringify(project.config.libraries) === JSON.stringify(["./slices"])
219
+ ) {
220
+ const sliceLibrary = await actions.readSliceLibrary({
221
+ libraryID: project.config.libraries[0],
222
+ });
223
+
224
+ if (sliceLibrary.sliceIDs.length < 1) {
225
+ project.config.libraries = ["./src/lib/slices"];
226
+ }
227
+ }
228
+
229
+ await helpers.updatePrismicConfig(project.config, {
230
+ format: options.format,
231
+ });
232
+ };
233
+
234
+ const upsertSliceLibraryIndexFiles = async (
235
+ context: PluginSystemContext<PluginOptions>,
236
+ ) => {
237
+ // We must use the `getProject()` helper to get the latest version of
238
+ // the project config. The config may have been modified in
239
+ // `modifyPrismicConfig()` and will not be reflected in
240
+ // `context.project`.
241
+ const project = await context.helpers.getProject();
242
+
243
+ if (!project.config.libraries) {
244
+ return;
245
+ }
246
+
247
+ await Promise.all(
248
+ project.config.libraries.map(async (libraryID) => {
249
+ await upsertSliceLibraryIndexFile({ libraryID, ...context });
250
+ }),
251
+ );
252
+ };
253
+
254
+ const modifyViteConfig = async ({
255
+ helpers,
256
+ options,
257
+ }: PluginSystemContext<PluginOptions>) => {
258
+ let filename = "vite.config.js";
259
+ if (!(await checkHasProjectFile({ filename, helpers }))) {
260
+ filename = "vite.config.ts";
261
+ }
262
+ if (!(await checkHasProjectFile({ filename, helpers }))) {
263
+ // Couldn't find the config file.
264
+ return;
265
+ }
266
+ const filepath = helpers.joinPathFromRoot(filename);
267
+
268
+ const mod = await loadFile(filepath);
269
+ if (mod.exports.default.$type !== "function-call") {
270
+ // Invalid config file.
271
+ return;
272
+ }
273
+
274
+ // Add `./prismic.config.json` to allowed files.
275
+ const config = mod.exports.default.$args[0];
276
+ config.server ??= {};
277
+ config.server.fs ??= {};
278
+ config.server.fs.allow ??= [];
279
+ if (!config.server.fs.allow.includes("./prismic.config.json")) {
280
+ config.server.fs.allow.push("./prismic.config.json");
281
+ }
282
+
283
+ // Remove an empty line above the `server` property.
284
+ const contents = mod.generate().code.replace(/\n\s*\n(?=\s*server:)/, "\n");
285
+
286
+ await writeProjectFile({
287
+ filename,
288
+ contents,
289
+ format: options.format,
290
+ helpers,
291
+ });
292
+ };
293
+
294
+ export const projectInit: ProjectInitHook<PluginOptions> = async (
295
+ { installDependencies: _installDependencies },
296
+ context,
297
+ ) => {
298
+ rejectIfNecessary(
299
+ await Promise.allSettled([
300
+ installDependencies({ installDependencies: _installDependencies }),
301
+ modifyPrismicConfig(context),
302
+ createPrismicIOFile(context),
303
+ createPreviewAPIRoute(context),
304
+ createPreviewRouteDirectory(context),
305
+ createPreviewRouteMatcherFile(context),
306
+ createRootLayoutServerFile(context),
307
+ createRootLayoutFile(context),
308
+ modifyViteConfig(context),
309
+ ]),
310
+ );
311
+
312
+ // This must happen after `modifyPrismicConfig()` since the
313
+ // location of the default Slice library may change.
314
+ await upsertSliceLibraryIndexFiles(context);
315
+ };
@@ -0,0 +1,82 @@
1
+ import TypesInternal from "@prismicio/types-internal/lib/customtypes/index.js";
2
+ import { source as svelte } from "common-tags";
3
+
4
+ import { pascalCase } from "../lib/pascalCase";
5
+
6
+ const PLACEHOLDER = `
7
+ Placeholder component for {slice.slice_type} (variation: {slice.variation}) slices.
8
+ <br />
9
+ <strong>You can edit this slice directly in your code editor.</strong>
10
+ <!--
11
+ 💡 Use the Prismic MCP server with your code editor
12
+ 📚 Docs: https://prismic.io/docs/ai#code-with-prismics-mcp-server
13
+ -->
14
+ `;
15
+
16
+ export function sliceTemplate(args: {
17
+ model: TypesInternal.SharedSlice;
18
+ typescript: boolean;
19
+ version: number;
20
+ }): string {
21
+ const { model, typescript, version } = args;
22
+
23
+ const pascalName = pascalCase(model.name);
24
+
25
+ const v5TS = svelte`
26
+ <script lang="ts">
27
+ import type { Content } from '@prismicio/client';
28
+ import type { SliceComponentProps } from '@prismicio/svelte';
29
+
30
+ type Props = SliceComponentProps<Content.${pascalName}Slice>;
31
+
32
+ const { slice }: Props = $props();
33
+ </script>
34
+
35
+ <section data-slice-type={slice.slice_type} data-slice-variation={slice.variation}>
36
+ ${PLACEHOLDER}
37
+ </section>
38
+ `;
39
+
40
+ const v5JS = svelte`
41
+ <script>
42
+ /* @typedef {import("@prismicio/client").Content} Content */
43
+ /* @typedef {import("@prismicio/svelte").SliceComponentProps} SliceComponentProps */
44
+
45
+ /* @type {SliceComponentProps<Content.${pascalName}Slice>} */
46
+ const { slice } = $props();
47
+ </script>
48
+
49
+ <section data-slice-type={slice.slice_type} data-slice-variation={slice.variation}>
50
+ ${PLACEHOLDER}
51
+ </section>
52
+ `;
53
+
54
+ const v4TS = svelte`
55
+ <script lang="ts">
56
+ import type { Content } from '@prismicio/client';
57
+
58
+ export let slice: Content.${pascalName}Slice;
59
+ </script>
60
+
61
+ <section data-slice-type={slice.slice_type} data-slice-variation={slice.variation}>
62
+ ${PLACEHOLDER}
63
+ </section>
64
+ `;
65
+
66
+ const v4JS = svelte`
67
+ <script>
68
+ /** @type {import("@prismicio/client").Content.${pascalName}Slice} */
69
+ export let slice;
70
+ </script>
71
+
72
+ <section data-slice-type={slice.slice_type} data-slice-variation={slice.variation}>
73
+ ${PLACEHOLDER}
74
+ </section>
75
+ `;
76
+
77
+ if (typescript) {
78
+ return version <= 4 ? v4TS : v5TS;
79
+ }
80
+
81
+ return version <= 4 ? v4JS : v5JS;
82
+ }
@@ -0,0 +1,84 @@
1
+ import type {
2
+ SliceCreateHook,
3
+ SliceCreateHookData,
4
+ PluginSystemContext,
5
+ } from "@prismicio/plugin-kit";
6
+ import {
7
+ upsertGlobalTypeScriptTypes,
8
+ writeSliceFile,
9
+ writeSliceModel,
10
+ } from "@prismicio/plugin-kit/fs";
11
+
12
+ import { checkIsTypeScriptProject } from "../lib/checkIsTypeScriptProject";
13
+ import { getSvelteMajor } from "../lib/getSvelteMajor";
14
+ import { rejectIfNecessary } from "../lib/rejectIfNecessary";
15
+ import { upsertSliceLibraryIndexFile } from "../lib/upsertSliceLibraryIndexFile";
16
+ import type { PluginOptions } from "../types";
17
+
18
+ import { sliceTemplate } from "./slice-create.templates";
19
+
20
+ type Args = {
21
+ data: SliceCreateHookData;
22
+ } & PluginSystemContext<PluginOptions>;
23
+
24
+ const createComponentFile = async ({
25
+ data,
26
+ helpers,
27
+ actions,
28
+ options,
29
+ }: Args) => {
30
+ const { model, componentContents } = data;
31
+
32
+ const typescript = await checkIsTypeScriptProject({ helpers, options });
33
+ const contents =
34
+ componentContents ??
35
+ sliceTemplate({ model, typescript, version: await getSvelteMajor() });
36
+
37
+ await writeSliceFile({
38
+ libraryID: data.libraryID,
39
+ model: data.model,
40
+ filename: "index.svelte",
41
+ contents,
42
+ format: options.format,
43
+ actions,
44
+ helpers,
45
+ formatOptions: {
46
+ prettier: {
47
+ plugins: ["prettier-plugin-svelte"],
48
+ parser: "svelte",
49
+ },
50
+ },
51
+ });
52
+ };
53
+
54
+ export const sliceCreate: SliceCreateHook<PluginOptions> = async (
55
+ data,
56
+ context,
57
+ ) => {
58
+ rejectIfNecessary(
59
+ await Promise.allSettled([
60
+ writeSliceModel({
61
+ libraryID: data.libraryID,
62
+ model: data.model,
63
+ format: context.options.format,
64
+ helpers: context.helpers,
65
+ }),
66
+ createComponentFile({ data, ...context }),
67
+ ]),
68
+ );
69
+
70
+ rejectIfNecessary(
71
+ await Promise.allSettled([
72
+ upsertSliceLibraryIndexFile({
73
+ libraryID: data.libraryID,
74
+ ...context,
75
+ }),
76
+ upsertGlobalTypeScriptTypes({
77
+ filename: context.options.generatedTypesFilePath,
78
+ format: context.options.format,
79
+ helpers: context.helpers,
80
+ actions: context.actions,
81
+ }),
82
+ ]),
83
+ );
84
+ };
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { plugin as default } from "./plugin";
2
+
3
+ export type { PluginOptions } from "./types";
@@ -0,0 +1,18 @@
1
+ import { PluginSystemContext } from "@prismicio/plugin-kit";
2
+ import { checkIsTypeScriptProject as baseCheckIsTypeScriptProject } from "@prismicio/plugin-kit/fs";
3
+
4
+ import { PluginOptions } from "../types";
5
+
6
+ type CheckIsTypeScriptProjectArgs = {
7
+ helpers: PluginSystemContext<PluginOptions>["helpers"];
8
+ options: PluginSystemContext<PluginOptions>["options"];
9
+ };
10
+
11
+ export const checkIsTypeScriptProject = async (
12
+ args: CheckIsTypeScriptProjectArgs,
13
+ ): Promise<boolean> => {
14
+ return (
15
+ args.options.typescript ??
16
+ baseCheckIsTypeScriptProject({ helpers: args.helpers })
17
+ );
18
+ };
@@ -0,0 +1,22 @@
1
+ import { PluginSystemContext } from "@prismicio/plugin-kit";
2
+
3
+ import { PluginOptions } from "../types";
4
+
5
+ import { checkIsTypeScriptProject } from "./checkIsTypeScriptProject";
6
+
7
+ type GetJSFileExtensionArgs = Pick<
8
+ PluginSystemContext<PluginOptions>,
9
+ "helpers" | "options"
10
+ >;
11
+
12
+ export const getJSFileExtension = async ({
13
+ helpers,
14
+ options,
15
+ }: GetJSFileExtensionArgs): Promise<string> => {
16
+ const isTypeScriptProject = await checkIsTypeScriptProject({
17
+ helpers,
18
+ options,
19
+ });
20
+
21
+ return isTypeScriptProject ? "ts" : "js";
22
+ };
@@ -0,0 +1,23 @@
1
+ import { join } from "node:path";
2
+
3
+ import { requireResolve } from "./requireResolve";
4
+
5
+ export const getSvelteMajor = async (): Promise<number> => {
6
+ // A dynamic import lets us easily mock the module.
7
+ const { readFile } = await import("node:fs/promises");
8
+
9
+ const packageJSONPath = requireResolve(
10
+ "svelte/package.json",
11
+ join(process.cwd(), "package.json"),
12
+ );
13
+ const { version } = JSON.parse(await readFile(packageJSONPath, "utf8"));
14
+
15
+ const major = Number.parseInt(version.split(".")[0]);
16
+ if (Number.isNaN(major)) {
17
+ throw new Error(
18
+ `Unable to parse svelte's installed version number: "${version}"`,
19
+ );
20
+ }
21
+
22
+ return major;
23
+ };
@@ -0,0 +1,12 @@
1
+ import { pascalCase as basePascalCase } from "pascal-case";
2
+
3
+ /**
4
+ * Converts a string to a Pascal cased string.
5
+ *
6
+ * @param input - String to convert into a Pascal cased string.
7
+ *
8
+ * @returns Pascal cased string version of `input`.
9
+ */
10
+ export const pascalCase = (...input: (string | undefined)[]): string => {
11
+ return basePascalCase(input.filter(Boolean).join(" "));
12
+ };
@@ -0,0 +1,16 @@
1
+ export const rejectIfNecessary = <
2
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3
+ TPromiseSettledResults extends readonly PromiseSettledResult<any>[],
4
+ >(
5
+ promiseSettledResults: TPromiseSettledResults,
6
+ ): void => {
7
+ const rejectedReasons = promiseSettledResults
8
+ .filter(
9
+ (result): result is PromiseRejectedResult => result.status === "rejected",
10
+ )
11
+ .map((result) => result.reason);
12
+
13
+ if (rejectedReasons.length > 0) {
14
+ throw rejectedReasons[0];
15
+ }
16
+ };
@@ -0,0 +1,30 @@
1
+ import _module, { createRequire } from "node:module";
2
+
3
+ /**
4
+ * Resolves a module path with `createRequire().resolve()` with Yarn PnP
5
+ * support.
6
+ *
7
+ * @param id - Module to resolve.
8
+ * @param from - Location to resolve the module from.
9
+ *
10
+ * @returns - Resolved module path.
11
+ */
12
+ export const requireResolve = (id: string, from: string): string => {
13
+ let resolvedID = id;
14
+
15
+ // Support Yarn PnP
16
+ if (
17
+ process.versions.pnp &&
18
+ "findPnpApi" in _module &&
19
+ typeof _module.findPnpApi === "function"
20
+ ) {
21
+ const pnpApi = _module.findPnpApi(from);
22
+ if (pnpApi) {
23
+ resolvedID = pnpApi.resolveRequest(id, from);
24
+ }
25
+ }
26
+
27
+ const require = createRequire(from);
28
+
29
+ return require.resolve(resolvedID);
30
+ };
@@ -0,0 +1,78 @@
1
+ import * as path from "node:path";
2
+
3
+ import { PluginSystemContext } from "@prismicio/plugin-kit";
4
+ import {
5
+ buildSliceDirectoryPath,
6
+ buildSliceLibraryDirectoryPath,
7
+ writeProjectFile,
8
+ } from "@prismicio/plugin-kit/fs";
9
+ import { stripIndent } from "common-tags";
10
+
11
+ import { NON_EDITABLE_FILE_BANNER } from "../constants";
12
+ import { PluginOptions } from "../types";
13
+
14
+ import { getJSFileExtension } from "./getJSFileExtension";
15
+ import { pascalCase } from "./pascalCase";
16
+
17
+ type UpsertSliceLibraryIndexFileArgs = {
18
+ libraryID: string;
19
+ } & PluginSystemContext<PluginOptions>;
20
+
21
+ export const upsertSliceLibraryIndexFile = async (
22
+ args: UpsertSliceLibraryIndexFileArgs,
23
+ ): Promise<void> => {
24
+ const slices = await args.actions.readAllSliceModelsForLibrary({
25
+ libraryID: args.libraryID,
26
+ });
27
+
28
+ const contents = stripIndent`
29
+ ${NON_EDITABLE_FILE_BANNER}
30
+
31
+ ${(
32
+ await Promise.all(
33
+ slices.map(async (slice) => {
34
+ const dirName = path.basename(
35
+ await buildSliceDirectoryPath({
36
+ model: slice.model,
37
+ helpers: args.helpers,
38
+ libraryID: args.libraryID,
39
+ }),
40
+ );
41
+ const componentName = pascalCase(slice.model.name);
42
+
43
+ return `import ${componentName} from "./${dirName}/index.svelte";`;
44
+ }),
45
+ )
46
+ ).join("\n")}
47
+
48
+ export const components = {
49
+ ${slices
50
+ .map((slice) => {
51
+ const id = slice.model.id;
52
+ const componentName = pascalCase(slice.model.name);
53
+
54
+ return `${id}: ${componentName},`;
55
+ })
56
+ .join("\n")}
57
+ }
58
+ `;
59
+
60
+ const extension = await getJSFileExtension({
61
+ helpers: args.helpers,
62
+ options: args.options,
63
+ });
64
+ const filePath = path.join(
65
+ buildSliceLibraryDirectoryPath({
66
+ libraryID: args.libraryID,
67
+ helpers: args.helpers,
68
+ }),
69
+ `index.${extension}`,
70
+ );
71
+
72
+ await writeProjectFile({
73
+ filename: filePath,
74
+ contents,
75
+ format: args.options.format,
76
+ helpers: args.helpers,
77
+ });
78
+ };