@prismicio/adapter-nuxt 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 (49) 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 +117 -0
  6. package/dist/hooks/project-init.js.map +1 -0
  7. package/dist/hooks/slice-create.d.ts +3 -0
  8. package/dist/hooks/slice-create.js +68 -0
  9. package/dist/hooks/slice-create.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.js +5 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/lib/buildSrcPath.d.ts +5 -0
  14. package/dist/lib/buildSrcPath.js +23 -0
  15. package/dist/lib/buildSrcPath.js.map +1 -0
  16. package/dist/lib/checkIsTypeScriptProject.d.ts +8 -0
  17. package/dist/lib/checkIsTypeScriptProject.js +8 -0
  18. package/dist/lib/checkIsTypeScriptProject.js.map +1 -0
  19. package/dist/lib/getJSFileExtension.d.ts +5 -0
  20. package/dist/lib/getJSFileExtension.js +12 -0
  21. package/dist/lib/getJSFileExtension.js.map +1 -0
  22. package/dist/lib/pascalCase.d.ts +8 -0
  23. package/dist/lib/pascalCase.js +8 -0
  24. package/dist/lib/pascalCase.js.map +1 -0
  25. package/dist/lib/rejectIfNecessary.d.ts +1 -0
  26. package/dist/lib/rejectIfNecessary.js +10 -0
  27. package/dist/lib/rejectIfNecessary.js.map +1 -0
  28. package/dist/lib/upsertSliceLibraryIndexFile.d.ts +7 -0
  29. package/dist/lib/upsertSliceLibraryIndexFile.js +74 -0
  30. package/dist/lib/upsertSliceLibraryIndexFile.js.map +1 -0
  31. package/dist/package.json.js +5 -0
  32. package/dist/package.json.js.map +1 -0
  33. package/dist/plugin.d.ts +2 -0
  34. package/dist/plugin.js +144 -0
  35. package/dist/plugin.js.map +1 -0
  36. package/dist/types.d.ts +34 -0
  37. package/package.json +79 -0
  38. package/src/constants.ts +5 -0
  39. package/src/hooks/project-init.ts +199 -0
  40. package/src/hooks/slice-create.ts +131 -0
  41. package/src/index.ts +5 -0
  42. package/src/lib/buildSrcPath.ts +30 -0
  43. package/src/lib/checkIsTypeScriptProject.ts +18 -0
  44. package/src/lib/getJSFileExtension.ts +22 -0
  45. package/src/lib/pascalCase.ts +12 -0
  46. package/src/lib/rejectIfNecessary.ts +16 -0
  47. package/src/lib/upsertSliceLibraryIndexFile.ts +110 -0
  48. package/src/plugin.ts +191 -0
  49. package/src/types.ts +38 -0
package/dist/plugin.js ADDED
@@ -0,0 +1,144 @@
1
+ import { definePlugin } from "@prismicio/plugin-kit";
2
+ import { writeSliceModel, upsertGlobalTypeScriptTypes, renameSlice, deleteSliceDirectory, readSliceModel, readSliceLibrary, writeCustomTypeModel, renameCustomType, deleteCustomTypeDirectory, readCustomTypeModel, readCustomTypeLibrary } from "@prismicio/plugin-kit/fs";
3
+ import { name } from "./package.json.js";
4
+ import { projectInit } from "./hooks/project-init.js";
5
+ import { sliceCreate } from "./hooks/slice-create.js";
6
+ import { rejectIfNecessary } from "./lib/rejectIfNecessary.js";
7
+ import { upsertSliceLibraryIndexFile } from "./lib/upsertSliceLibraryIndexFile.js";
8
+ const plugin = definePlugin({
9
+ meta: {
10
+ name
11
+ },
12
+ defaultOptions: {
13
+ format: true,
14
+ lazyLoadSlices: true
15
+ },
16
+ setup({ hook }) {
17
+ hook("project:init", projectInit);
18
+ hook("slice:create", sliceCreate);
19
+ hook("slice:update", async (data, context) => {
20
+ await writeSliceModel({
21
+ libraryID: data.libraryID,
22
+ model: data.model,
23
+ ...context
24
+ });
25
+ await upsertGlobalTypeScriptTypes({
26
+ filename: context.options.generatedTypesFilePath,
27
+ format: context.options.format,
28
+ ...context
29
+ });
30
+ });
31
+ hook("slice:rename", async (data, context) => {
32
+ await renameSlice({
33
+ libraryID: data.libraryID,
34
+ model: data.model,
35
+ format: context.options.format,
36
+ ...context
37
+ });
38
+ rejectIfNecessary(await Promise.allSettled([
39
+ upsertSliceLibraryIndexFile({
40
+ libraryID: data.libraryID,
41
+ ...context
42
+ }),
43
+ upsertGlobalTypeScriptTypes({
44
+ filename: context.options.generatedTypesFilePath,
45
+ format: context.options.format,
46
+ ...context
47
+ })
48
+ ]));
49
+ });
50
+ hook("slice:delete", async (data, context) => {
51
+ await deleteSliceDirectory({
52
+ libraryID: data.libraryID,
53
+ model: data.model,
54
+ ...context
55
+ });
56
+ rejectIfNecessary(await Promise.allSettled([
57
+ upsertSliceLibraryIndexFile({
58
+ libraryID: data.libraryID,
59
+ ...context
60
+ }),
61
+ upsertGlobalTypeScriptTypes({
62
+ filename: context.options.generatedTypesFilePath,
63
+ format: context.options.format,
64
+ ...context
65
+ })
66
+ ]));
67
+ });
68
+ hook("slice:read", async (data, context) => {
69
+ return await readSliceModel({
70
+ libraryID: data.libraryID,
71
+ sliceID: data.sliceID,
72
+ ...context
73
+ });
74
+ });
75
+ hook("slice-library:read", async (data, context) => {
76
+ return await readSliceLibrary({
77
+ libraryID: data.libraryID,
78
+ ...context
79
+ });
80
+ });
81
+ hook("custom-type:create", async (data, context) => {
82
+ await writeCustomTypeModel({
83
+ model: data.model,
84
+ format: context.options.format,
85
+ ...context
86
+ });
87
+ await upsertGlobalTypeScriptTypes({
88
+ filename: context.options.generatedTypesFilePath,
89
+ format: context.options.format,
90
+ ...context
91
+ });
92
+ });
93
+ hook("custom-type:update", async (data, context) => {
94
+ await writeCustomTypeModel({
95
+ model: data.model,
96
+ format: context.options.format,
97
+ ...context
98
+ });
99
+ await upsertGlobalTypeScriptTypes({
100
+ filename: context.options.generatedTypesFilePath,
101
+ format: context.options.format,
102
+ ...context
103
+ });
104
+ });
105
+ hook("custom-type:rename", async (data, context) => {
106
+ await renameCustomType({
107
+ model: data.model,
108
+ format: context.options.format,
109
+ ...context
110
+ });
111
+ await upsertGlobalTypeScriptTypes({
112
+ filename: context.options.generatedTypesFilePath,
113
+ format: context.options.format,
114
+ ...context
115
+ });
116
+ });
117
+ hook("custom-type:delete", async (data, context) => {
118
+ await deleteCustomTypeDirectory({
119
+ customTypeID: data.model.id,
120
+ ...context
121
+ });
122
+ await upsertGlobalTypeScriptTypes({
123
+ filename: context.options.generatedTypesFilePath,
124
+ format: context.options.format,
125
+ ...context
126
+ });
127
+ });
128
+ hook("custom-type:read", async (data, context) => {
129
+ return await readCustomTypeModel({
130
+ customTypeID: data.id,
131
+ ...context
132
+ });
133
+ });
134
+ hook("custom-type-library:read", async (_data, context) => {
135
+ return await readCustomTypeLibrary({
136
+ helpers: context.helpers
137
+ });
138
+ });
139
+ }
140
+ });
141
+ export {
142
+ plugin
143
+ };
144
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import { definePlugin } from \"@prismicio/plugin-kit\";\nimport {\n\tdeleteCustomTypeDirectory,\n\tdeleteSliceDirectory,\n\treadCustomTypeLibrary,\n\treadCustomTypeModel,\n\treadSliceLibrary,\n\treadSliceModel,\n\trenameCustomType,\n\trenameSlice,\n\tupsertGlobalTypeScriptTypes,\n\twriteCustomTypeModel,\n\twriteSliceModel,\n} from \"@prismicio/plugin-kit/fs\";\n\nimport { name as pkgName } from \"../package.json\";\n\nimport { projectInit } from \"./hooks/project-init\";\nimport { sliceCreate } from \"./hooks/slice-create\";\nimport { rejectIfNecessary } from \"./lib/rejectIfNecessary\";\nimport { upsertSliceLibraryIndexFile } from \"./lib/upsertSliceLibraryIndexFile\";\nimport { PluginOptions } from \"./types\";\n\nexport const plugin = definePlugin<PluginOptions>({\n\tmeta: {\n\t\tname: pkgName,\n\t},\n\tdefaultOptions: {\n\t\tformat: true,\n\t\tlazyLoadSlices: true,\n\t},\n\tsetup({ hook }) {\n\t\t////////////////////////////////////////////////////////////////\n\t\t// project:*\n\t\t////////////////////////////////////////////////////////////////\n\n\t\thook(\"project:init\", projectInit);\n\n\t\t////////////////////////////////////////////////////////////////\n\t\t// slice:*\n\t\t////////////////////////////////////////////////////////////////\n\n\t\thook(\"slice:create\", sliceCreate);\n\t\thook(\"slice:update\", async (data, context) => {\n\t\t\tawait writeSliceModel({\n\t\t\t\tlibraryID: data.libraryID,\n\t\t\t\tmodel: data.model,\n\t\t\t\t...context,\n\t\t\t});\n\n\t\t\tawait upsertGlobalTypeScriptTypes({\n\t\t\t\tfilename: context.options.generatedTypesFilePath,\n\t\t\t\tformat: context.options.format,\n\t\t\t\t...context,\n\t\t\t});\n\t\t});\n\t\thook(\"slice:rename\", async (data, context) => {\n\t\t\tawait renameSlice({\n\t\t\t\tlibraryID: data.libraryID,\n\t\t\t\tmodel: data.model,\n\t\t\t\tformat: context.options.format,\n\t\t\t\t...context,\n\t\t\t});\n\n\t\t\trejectIfNecessary(\n\t\t\t\tawait Promise.allSettled([\n\t\t\t\t\tupsertSliceLibraryIndexFile({\n\t\t\t\t\t\tlibraryID: data.libraryID,\n\t\t\t\t\t\t...context,\n\t\t\t\t\t}),\n\t\t\t\t\tupsertGlobalTypeScriptTypes({\n\t\t\t\t\t\tfilename: context.options.generatedTypesFilePath,\n\t\t\t\t\t\tformat: context.options.format,\n\t\t\t\t\t\t...context,\n\t\t\t\t\t}),\n\t\t\t\t]),\n\t\t\t);\n\t\t});\n\t\thook(\"slice:delete\", async (data, context) => {\n\t\t\tawait deleteSliceDirectory({\n\t\t\t\tlibraryID: data.libraryID,\n\t\t\t\tmodel: data.model,\n\t\t\t\t...context,\n\t\t\t});\n\n\t\t\trejectIfNecessary(\n\t\t\t\tawait Promise.allSettled([\n\t\t\t\t\tupsertSliceLibraryIndexFile({\n\t\t\t\t\t\tlibraryID: data.libraryID,\n\t\t\t\t\t\t...context,\n\t\t\t\t\t}),\n\t\t\t\t\tupsertGlobalTypeScriptTypes({\n\t\t\t\t\t\tfilename: context.options.generatedTypesFilePath,\n\t\t\t\t\t\tformat: context.options.format,\n\t\t\t\t\t\t...context,\n\t\t\t\t\t}),\n\t\t\t\t]),\n\t\t\t);\n\t\t});\n\t\thook(\"slice:read\", async (data, context) => {\n\t\t\treturn await readSliceModel({\n\t\t\t\tlibraryID: data.libraryID,\n\t\t\t\tsliceID: data.sliceID,\n\t\t\t\t...context,\n\t\t\t});\n\t\t});\n\n\t\t////////////////////////////////////////////////////////////////\n\t\t// slice-library:*\n\t\t////////////////////////////////////////////////////////////////\n\n\t\thook(\"slice-library:read\", async (data, context) => {\n\t\t\treturn await readSliceLibrary({\n\t\t\t\tlibraryID: data.libraryID,\n\t\t\t\t...context,\n\t\t\t});\n\t\t});\n\n\t\t////////////////////////////////////////////////////////////////\n\t\t// custom-type:*\n\t\t////////////////////////////////////////////////////////////////\n\n\t\thook(\"custom-type:create\", async (data, context) => {\n\t\t\tawait writeCustomTypeModel({\n\t\t\t\tmodel: data.model,\n\t\t\t\tformat: context.options.format,\n\t\t\t\t...context,\n\t\t\t});\n\n\t\t\tawait upsertGlobalTypeScriptTypes({\n\t\t\t\tfilename: context.options.generatedTypesFilePath,\n\t\t\t\tformat: context.options.format,\n\t\t\t\t...context,\n\t\t\t});\n\t\t});\n\t\thook(\"custom-type:update\", async (data, context) => {\n\t\t\tawait writeCustomTypeModel({\n\t\t\t\tmodel: data.model,\n\t\t\t\tformat: context.options.format,\n\t\t\t\t...context,\n\t\t\t});\n\n\t\t\tawait upsertGlobalTypeScriptTypes({\n\t\t\t\tfilename: context.options.generatedTypesFilePath,\n\t\t\t\tformat: context.options.format,\n\t\t\t\t...context,\n\t\t\t});\n\t\t});\n\t\thook(\"custom-type:rename\", async (data, context) => {\n\t\t\tawait renameCustomType({\n\t\t\t\tmodel: data.model,\n\t\t\t\tformat: context.options.format,\n\t\t\t\t...context,\n\t\t\t});\n\n\t\t\tawait upsertGlobalTypeScriptTypes({\n\t\t\t\tfilename: context.options.generatedTypesFilePath,\n\t\t\t\tformat: context.options.format,\n\t\t\t\t...context,\n\t\t\t});\n\t\t});\n\t\thook(\"custom-type:delete\", async (data, context) => {\n\t\t\tawait deleteCustomTypeDirectory({\n\t\t\t\tcustomTypeID: data.model.id,\n\t\t\t\t...context,\n\t\t\t});\n\n\t\t\tawait upsertGlobalTypeScriptTypes({\n\t\t\t\tfilename: context.options.generatedTypesFilePath,\n\t\t\t\tformat: context.options.format,\n\t\t\t\t...context,\n\t\t\t});\n\t\t});\n\t\thook(\"custom-type:read\", async (data, context) => {\n\t\t\treturn await readCustomTypeModel({\n\t\t\t\tcustomTypeID: data.id,\n\t\t\t\t...context,\n\t\t\t});\n\t\t});\n\n\t\t////////////////////////////////////////////////////////////////\n\t\t// custom-type-library:*\n\t\t////////////////////////////////////////////////////////////////\n\n\t\thook(\"custom-type-library:read\", async (_data, context) => {\n\t\t\treturn await readCustomTypeLibrary({\n\t\t\t\thelpers: context.helpers,\n\t\t\t});\n\t\t});\n\t},\n});\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export type PluginOptions = {
2
+ /**
3
+ * Determines if generated files should be formatted using Prettier.
4
+ *
5
+ * @defaultValue `true`
6
+ */
7
+ format?: boolean;
8
+ /**
9
+ * Determines if Slice components should be lazy loaded when rendered.
10
+ *
11
+ * @defaultValue `true`
12
+ */
13
+ lazyLoadSlices?: boolean;
14
+ /**
15
+ * Determines if generated files should be written in TypeScript or
16
+ * JavaScript.
17
+ *
18
+ * @defaultValue `true` if the project contains a `tsconfig.json`, `false` otherwise.
19
+ */
20
+ typescript?: boolean;
21
+ /**
22
+ * The filepath at which generated TypeScript types will be saved.
23
+ *
24
+ * @defaultValue `prismicio-types.d.ts`
25
+ */
26
+ generatedTypesFilePath?: string;
27
+ /**
28
+ * The filepath at which the active Prismic environment is stored as an
29
+ * environment variable.
30
+ *
31
+ * @defaultValue `.env.local`
32
+ */
33
+ environmentVariableFilePath?: string;
34
+ };
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@prismicio/adapter-nuxt",
3
+ "version": "0.0.1",
4
+ "description": "Prismic adapter for Nuxt.",
5
+ "keywords": [
6
+ "typescript",
7
+ "prismic"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "ssh://git@github.com/prismicio/devtools.git",
12
+ "directory": "packages/adapter-nuxt"
13
+ },
14
+ "license": "Apache-2.0",
15
+ "author": "Prismic <contact@prismic.io> (https://prismic.io)",
16
+ "type": "module",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ },
22
+ "./package.json": "./package.json"
23
+ },
24
+ "main": "dist/index.js",
25
+ "module": "dist/index.js",
26
+ "types": "dist/index.d.ts",
27
+ "typesVersions": {
28
+ "*": {
29
+ "*": [
30
+ "dist/index.d.ts"
31
+ ]
32
+ }
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "src"
37
+ ],
38
+ "engines": {
39
+ "node": ">=20.19.0"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "scripts": {
45
+ "build": "vite build",
46
+ "dev": "vite build --watch",
47
+ "types": "tsc --noEmit",
48
+ "format": "prettier --write .",
49
+ "lint": "eslint --max-warnings 0 .",
50
+ "prepack": "$npm_execpath run build",
51
+ "depcheck": "depcheck --config=.depcheckrc",
52
+ "audit": "yarn npm audit --environment production --severity high"
53
+ },
54
+ "dependencies": {
55
+ "@prismicio/plugin-kit": "0.0.1",
56
+ "common-tags": "1.8.2",
57
+ "magicast": "0.5.1",
58
+ "pascal-case": "3.1.2"
59
+ },
60
+ "devDependencies": {
61
+ "@eslint/js": "9.28.0",
62
+ "@trivago/prettier-plugin-sort-imports": "6.0.0",
63
+ "@types/common-tags": "1.8.4",
64
+ "depcheck": "1.4.7",
65
+ "eslint": "9.39.1",
66
+ "eslint-config-prettier": "10.1.8",
67
+ "eslint-plugin-tsdoc": "0.5.0",
68
+ "nuxt": "4.2.1",
69
+ "prettier": "3.7.1",
70
+ "prettier-plugin-jsdoc": "1.7.0",
71
+ "typescript": "5.9.3",
72
+ "typescript-eslint": "8.33.0",
73
+ "vite": "7.2.4",
74
+ "vite-plugin-sdk": "0.1.5"
75
+ },
76
+ "peerDependencies": {
77
+ "nuxt": "^3.0.0 || ^4.0.0"
78
+ }
79
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Banner text added to files that should not be edited by users.
3
+ */
4
+ export const NON_EDITABLE_FILE_BANNER =
5
+ "// Code generated by Prismic. DO NOT EDIT.";
@@ -0,0 +1,199 @@
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
+ deleteProjectFile,
11
+ readProjectFile,
12
+ writeProjectFile,
13
+ } from "@prismicio/plugin-kit/fs";
14
+ import { builders, loadFile, writeFile } from "magicast";
15
+
16
+ import { buildSrcPath } from "../lib/buildSrcPath";
17
+ import { rejectIfNecessary } from "../lib/rejectIfNecessary";
18
+ import type { PluginOptions } from "../types";
19
+
20
+ const NUXT_PRISMIC = "@nuxtjs/prismic";
21
+
22
+ type InstallDependenciesArgs = {
23
+ installDependencies: ProjectInitHookData["installDependencies"];
24
+ };
25
+
26
+ const installDependencies = async ({
27
+ installDependencies,
28
+ }: InstallDependenciesArgs) => {
29
+ await installDependencies({
30
+ dependencies: {
31
+ [NUXT_PRISMIC]: "^4.0.0",
32
+ },
33
+ dev: true,
34
+ });
35
+ };
36
+
37
+ type ConfigurePrismicModuleArgs = PluginSystemContext<PluginOptions>;
38
+
39
+ const configurePrismicModule = async ({
40
+ helpers,
41
+ }: ConfigurePrismicModuleArgs) => {
42
+ let nuxtConfigFilename = "nuxt.config.js";
43
+
44
+ if (!(await checkHasProjectFile({ filename: nuxtConfigFilename, helpers }))) {
45
+ nuxtConfigFilename = "nuxt.config.ts";
46
+
47
+ // nuxt.config.* not found
48
+ if (
49
+ !(await checkHasProjectFile({ filename: nuxtConfigFilename, helpers }))
50
+ ) {
51
+ return;
52
+ }
53
+ }
54
+
55
+ const nuxtConfigPath = helpers.joinPathFromRoot(nuxtConfigFilename);
56
+
57
+ const mod = await loadFile(nuxtConfigPath);
58
+ const config =
59
+ mod.exports.default.$type === "function-call"
60
+ ? mod.exports.default.$args[0]
61
+ : mod.exports.default;
62
+
63
+ // Register Prismic module
64
+ let hasInlinedConfiguration = false;
65
+ const hasPrismicModuleRegistered = (config.modules || []).find(
66
+ (registration: string | [string, unknown]) => {
67
+ if (typeof registration === "string") {
68
+ return registration === NUXT_PRISMIC;
69
+ } else if (Array.isArray(registration)) {
70
+ hasInlinedConfiguration = !!registration[1];
71
+
72
+ return registration[0] === NUXT_PRISMIC;
73
+ }
74
+
75
+ return false;
76
+ },
77
+ );
78
+
79
+ if (!hasPrismicModuleRegistered) {
80
+ config.modules ||= [];
81
+ config.modules.push(NUXT_PRISMIC);
82
+ }
83
+
84
+ // Append Prismic module configuration
85
+ if (!hasInlinedConfiguration) {
86
+ // Import Prismic configuration
87
+ mod.imports.$add({
88
+ from: "./prismic.config.json",
89
+ imported: "apiEndpoint",
90
+ });
91
+ mod.imports.$add({
92
+ from: "./prismic.config.json",
93
+ imported: "repositoryName",
94
+ });
95
+
96
+ // Add inline configuration
97
+ config.prismic ||= {};
98
+ config.prismic.endpoint = builders.raw("apiEndpoint || repositoryName");
99
+ }
100
+
101
+ await writeFile(mod, nuxtConfigPath);
102
+ };
103
+
104
+ const moveOrDeleteAppVue = async ({
105
+ helpers,
106
+ options,
107
+ }: PluginSystemContext<PluginOptions>) => {
108
+ const filenameAppVue = await buildSrcPath({ filename: "app.vue", helpers });
109
+
110
+ // If there's no `app.vue`, there's nothing to do.
111
+ if (!(await checkHasProjectFile({ filename: filenameAppVue, helpers }))) {
112
+ return;
113
+ }
114
+
115
+ const filecontentAppVue = await readProjectFile({
116
+ filename: filenameAppVue,
117
+ helpers,
118
+ encoding: "utf-8",
119
+ });
120
+
121
+ // We check for app.vue to contain Nuxt default welcome component to determine
122
+ // if we need to consider it as the default one or not.
123
+ if (!filecontentAppVue.includes("<NuxtWelcome")) {
124
+ return;
125
+ }
126
+
127
+ const filenameIndexVue = await buildSrcPath({
128
+ filename: path.join("pages/index.vue"),
129
+ helpers,
130
+ });
131
+
132
+ // If we don't have an `index.vue` we create one with the content of `app.vue`
133
+ if (!(await checkHasProjectFile({ filename: filenameIndexVue, helpers }))) {
134
+ await writeProjectFile({
135
+ filename: filenameIndexVue,
136
+ contents: filecontentAppVue,
137
+ format: options.format,
138
+ helpers,
139
+ });
140
+ }
141
+
142
+ // Delete `app.vue`
143
+ await deleteProjectFile({
144
+ filename: filenameAppVue,
145
+ helpers,
146
+ });
147
+ };
148
+
149
+ const modifyPrismicConfig = async ({
150
+ helpers,
151
+ options,
152
+ actions,
153
+ }: PluginSystemContext<PluginOptions>) => {
154
+ const hasAppDirectory = await checkHasProjectFile({
155
+ filename: "app",
156
+ helpers,
157
+ });
158
+ const hasSrcDirectory = await checkHasProjectFile({
159
+ filename: "src",
160
+ helpers,
161
+ });
162
+ const project = await helpers.getProject();
163
+
164
+ // Nest the default Slice Library in the `app` or `src` directory if it
165
+ // exists and is empty.
166
+ if (
167
+ (hasAppDirectory || hasSrcDirectory) &&
168
+ project.config.libraries &&
169
+ JSON.stringify(project.config.libraries) === JSON.stringify(["./slices"])
170
+ ) {
171
+ const sliceLibrary = await actions.readSliceLibrary({
172
+ libraryID: project.config.libraries[0],
173
+ });
174
+
175
+ if (sliceLibrary.sliceIDs.length < 1) {
176
+ project.config.libraries = hasAppDirectory
177
+ ? ["./app/slices"]
178
+ : ["./src/slices"];
179
+ }
180
+ }
181
+
182
+ await helpers.updatePrismicConfig(project.config, {
183
+ format: options.format,
184
+ });
185
+ };
186
+
187
+ export const projectInit: ProjectInitHook<PluginOptions> = async (
188
+ { installDependencies: _installDependencies },
189
+ context,
190
+ ) => {
191
+ rejectIfNecessary(
192
+ await Promise.allSettled([
193
+ installDependencies({ installDependencies: _installDependencies }),
194
+ configurePrismicModule(context),
195
+ moveOrDeleteAppVue(context),
196
+ modifyPrismicConfig(context),
197
+ ]),
198
+ );
199
+ };
@@ -0,0 +1,131 @@
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
+ import { stripIndent } from "common-tags";
12
+
13
+ import { checkIsTypeScriptProject } from "../lib/checkIsTypeScriptProject";
14
+ import { pascalCase } from "../lib/pascalCase";
15
+ import { rejectIfNecessary } from "../lib/rejectIfNecessary";
16
+ import { upsertSliceLibraryIndexFile } from "../lib/upsertSliceLibraryIndexFile";
17
+ import type { PluginOptions } from "../types";
18
+
19
+ type CreateComponentFileArgs = {
20
+ data: SliceCreateHookData;
21
+ } & PluginSystemContext<PluginOptions>;
22
+
23
+ const createComponentFile = async ({
24
+ data,
25
+ helpers,
26
+ actions,
27
+ options,
28
+ }: CreateComponentFileArgs) => {
29
+ const pascalName = pascalCase(data.model.name);
30
+
31
+ let contents: string;
32
+
33
+ const isTypeScriptProject = await checkIsTypeScriptProject({
34
+ helpers,
35
+ options,
36
+ });
37
+
38
+ const placeholderInstructions = `
39
+ <br />
40
+ <strong>You can edit this slice directly in your code editor.</strong>
41
+ <!--
42
+ 💡 Use the Prismic MCP server with your code editor
43
+ 📚 Docs: https://prismic.io/docs/ai#code-with-prismics-mcp-server
44
+ -->`;
45
+
46
+ if (data.componentContents) {
47
+ contents = data.componentContents;
48
+ } else if (isTypeScriptProject) {
49
+ contents = stripIndent`
50
+ <script setup lang="ts">
51
+ import type { Content } from "@prismicio/client";
52
+
53
+ // The array passed to \`getSliceComponentProps\` is purely optional.
54
+ // Consider it as a visual hint for you when templating your slice.
55
+ defineProps(getSliceComponentProps<Content.${pascalName}Slice>(
56
+ ["slice", "index", "slices", "context"]
57
+ ));
58
+ </script>
59
+
60
+ <template>
61
+ <section
62
+ :data-slice-type="slice.slice_type"
63
+ :data-slice-variation="slice.variation"
64
+ >
65
+ Placeholder component for ${data.model.id} (variation: {{ slice.variation }}) slices.
66
+ ${placeholderInstructions}
67
+ </section>
68
+ </template>
69
+ `;
70
+ } else {
71
+ contents = stripIndent`
72
+ <script setup>
73
+ // The array passed to \`getSliceComponentProps\` is purely optional.
74
+ // Consider it as a visual hint for you when templating your slice.
75
+ defineProps(getSliceComponentProps(["slice", "index", "slices", "context"]));
76
+ </script>
77
+
78
+ <template>
79
+ <section
80
+ :data-slice-type="slice.slice_type"
81
+ :data-slice-variation="slice.variation"
82
+ >
83
+ Placeholder component for {{ model.id }} (variation: {{ slice.variation }}) slices.
84
+ ${placeholderInstructions}
85
+ </section>
86
+ </template>
87
+ `;
88
+ }
89
+
90
+ await writeSliceFile({
91
+ libraryID: data.libraryID,
92
+ model: data.model,
93
+ filename: "index.vue",
94
+ contents,
95
+ format: options.format,
96
+ actions,
97
+ helpers,
98
+ });
99
+ };
100
+
101
+ export const sliceCreate: SliceCreateHook<PluginOptions> = async (
102
+ data,
103
+ context,
104
+ ) => {
105
+ rejectIfNecessary(
106
+ await Promise.allSettled([
107
+ writeSliceModel({
108
+ libraryID: data.libraryID,
109
+ model: data.model,
110
+ format: context.options.format,
111
+ helpers: context.helpers,
112
+ }),
113
+ createComponentFile({ data, ...context }),
114
+ ]),
115
+ );
116
+
117
+ rejectIfNecessary(
118
+ await Promise.allSettled([
119
+ upsertSliceLibraryIndexFile({
120
+ libraryID: data.libraryID,
121
+ ...context,
122
+ }),
123
+ upsertGlobalTypeScriptTypes({
124
+ filename: context.options.generatedTypesFilePath,
125
+ format: context.options.format,
126
+ helpers: context.helpers,
127
+ actions: context.actions,
128
+ }),
129
+ ]),
130
+ );
131
+ };
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { plugin } from "./plugin";
2
+
3
+ export default plugin;
4
+
5
+ export type { PluginOptions } from "./types";
@@ -0,0 +1,30 @@
1
+ // TODO: If Nuxt provides a way to read `nuxt.config.js`'s `srcDir` value, we
2
+ // can use the exact value given. The current implementation does not support
3
+ // custom values different than "app" or "src".
4
+ import * as path from "node:path";
5
+
6
+ import { PluginSystemHelpers } from "@prismicio/plugin-kit";
7
+ import { checkHasProjectFile } from "@prismicio/plugin-kit/fs";
8
+
9
+ export async function buildSrcPath(args: {
10
+ filename: string;
11
+ helpers: PluginSystemHelpers;
12
+ }): Promise<string> {
13
+ const hasAppDirectory = await checkHasProjectFile({
14
+ filename: "app",
15
+ helpers: args.helpers,
16
+ });
17
+ if (hasAppDirectory) {
18
+ return path.join("app", args.filename);
19
+ }
20
+
21
+ const hasSrcDirectory = await checkHasProjectFile({
22
+ filename: "src",
23
+ helpers: args.helpers,
24
+ });
25
+ if (hasSrcDirectory) {
26
+ return path.join("src", args.filename);
27
+ }
28
+
29
+ return args.filename;
30
+ }
@@ -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
+ };