sveltekit-data-plugin 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # Sveltekit Data Plugin
2
+
3
+ Quite a mouthful. This tries to be a plugin for importing data easily, including the elephant in the room, images.
4
+
5
+ This is designed to use with `@sveltejs/enhanced-img` and will turn your image assets into valid `Picture` objects to pass directly to your `<enhanced:img/>` components, from markdown files in a folder, generated by something like [Netlify CMS](https://decapcms.org/docs/intro/)
6
+
7
+ ## Install
8
+
9
+ ```
10
+ npm install -D sveltekit-data-plugin
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ In your `vite.config.js` file
16
+
17
+ ```vite.config.js
18
+ import SveltekitData from 'sveltekit-data-plugin';
19
+ import { enhancedImages } from '@sveltejs/enhanced-img';
20
+
21
+ export default defineConfig({
22
+ plugins: [
23
+ SveltekitData(enhancedImages()),
24
+ ]
25
+ })
26
+ ```
27
+
28
+ This is optional, but creating a data alias in `svelte.config.js` is also nice for this
29
+
30
+ ```svelte.config.js
31
+ const config = {
32
+ kit: {
33
+ alias: {
34
+ $data: './src/data'
35
+ },
36
+ },
37
+ };
38
+
39
+ export default config;
40
+ ```
41
+
42
+ Then you can import a markdown file in a `page.js`, or whatever, like
43
+
44
+ ```page.js
45
+ /** @type {import('./$types').PageLoad} */
46
+ export async function load() {
47
+ const d = await import('$data/home.md').then((mod) => mod.default);
48
+
49
+ return d;
50
+ }
51
+ ```
52
+
53
+ And you will get a front-matter parsed markdown file
package/dist/plugin.js ADDED
@@ -0,0 +1,109 @@
1
+ (function(global, factory) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory(require("front-matter"), require("path"), require("fs/promises")) : typeof define === "function" && define.amd ? define(["front-matter", "path", "fs/promises"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global["Sveltekit Data Plugin"] = factory(global.fm, global.path, global.fs));
3
+ })(this, function(fm, path, fs) {
4
+ "use strict";
5
+ function stampURL(src, base) {
6
+ return `${path.resolve(base, src)}?enhanced`;
7
+ }
8
+ function parseObject(str) {
9
+ const updated = str.replaceAll(/{(\n\s*)?/gm, '{"').replaceAll(":", '":').replaceAll(/,(\n\s*)?([^ ])/g, ',"$2');
10
+ try {
11
+ return JSON.parse(updated);
12
+ } catch {
13
+ throw new Error(`Failed parsing string to object: ${str}`);
14
+ }
15
+ }
16
+ async function convert(opts, obj, base, depth = 1) {
17
+ if (typeof obj !== "object") {
18
+ if (typeof obj === "string" && /^\S*(jpg|png|webp|avif|jpeg)$/.test(obj)) {
19
+ const img = await opts.imagetools_plugin.load.call(
20
+ opts.plugin_context,
21
+ stampURL(obj, base)
22
+ );
23
+ return parseObject(img.slice("export default".length, -1));
24
+ }
25
+ if (typeof obj === "string" && /^\S*(.md)$/.test(obj) && depth === 1) {
26
+ try {
27
+ const contents = await fs.readFile(path.resolve(base, obj), "utf-8");
28
+ const data = fm(contents);
29
+ const attributes = await convert(
30
+ opts,
31
+ data.attributes,
32
+ base,
33
+ depth + 1
34
+ );
35
+ return {
36
+ attributes: {
37
+ ...attributes,
38
+ id: path.basename(obj)
39
+ },
40
+ body: data.body
41
+ };
42
+ } catch {
43
+ return obj;
44
+ }
45
+ }
46
+ return obj;
47
+ }
48
+ const entries = await Promise.all(
49
+ Object.entries(obj).map(async ([key, value]) => {
50
+ if (Array.isArray(value)) {
51
+ const values = await Promise.all(
52
+ value.map((item) => convert(opts, item, base))
53
+ );
54
+ return [key, values];
55
+ }
56
+ const v = await convert(opts, value, base);
57
+ return [key, v];
58
+ })
59
+ );
60
+ return entries.reduce((dict, curr) => {
61
+ return {
62
+ ...dict,
63
+ [curr[0]]: curr[1]
64
+ };
65
+ }, {});
66
+ }
67
+ function importDataPlugin(imagetools_plugin, { base = "./src/data" } = {}) {
68
+ const opts = {
69
+ /** @type {import('rollup').PluginContext | null} */
70
+ plugin_context: null,
71
+ /** @type {import('vite').ResolvedConfig | null} */
72
+ vite_config: null,
73
+ imagetools_plugin,
74
+ base
75
+ };
76
+ return {
77
+ name: "import-data",
78
+ enforce: "pre",
79
+ configResolved(config) {
80
+ opts.vite_config = config;
81
+ },
82
+ buildStart() {
83
+ opts.plugin_context = this;
84
+ },
85
+ async transform(src, id) {
86
+ var _a;
87
+ if (/\.(md)$/.test(id)) {
88
+ const base2 = path.resolve(((_a = opts.vite_config) == null ? void 0 : _a.root) ?? "", opts.base);
89
+ const d = fm(src);
90
+ const attributes = await convert(opts, d.attributes, base2);
91
+ return `export default ${JSON.stringify({
92
+ attributes,
93
+ body: d.body
94
+ })}`;
95
+ }
96
+ }
97
+ };
98
+ }
99
+ function plugin(imagePlugins) {
100
+ const enhancedImagesPlugin = imagePlugins.find(
101
+ (item) => item.name === "imagetools"
102
+ );
103
+ if (!enhancedImagesPlugin) {
104
+ throw new Error("Cannot find enhanced image plugin");
105
+ }
106
+ return [importDataPlugin(enhancedImagesPlugin), ...imagePlugins];
107
+ }
108
+ return plugin;
109
+ });
@@ -0,0 +1,109 @@
1
+ import fm from "front-matter";
2
+ import path from "path";
3
+ import fs from "fs/promises";
4
+ function stampURL(src, base) {
5
+ return `${path.resolve(base, src)}?enhanced`;
6
+ }
7
+ function parseObject(str) {
8
+ const updated = str.replaceAll(/{(\n\s*)?/gm, '{"').replaceAll(":", '":').replaceAll(/,(\n\s*)?([^ ])/g, ',"$2');
9
+ try {
10
+ return JSON.parse(updated);
11
+ } catch {
12
+ throw new Error(`Failed parsing string to object: ${str}`);
13
+ }
14
+ }
15
+ async function convert(opts, obj, base, depth = 1) {
16
+ if (typeof obj !== "object") {
17
+ if (typeof obj === "string" && /^\S*(jpg|png|webp|avif|jpeg)$/.test(obj)) {
18
+ const img = await opts.imagetools_plugin.load.call(
19
+ opts.plugin_context,
20
+ stampURL(obj, base)
21
+ );
22
+ return parseObject(img.slice("export default".length, -1));
23
+ }
24
+ if (typeof obj === "string" && /^\S*(.md)$/.test(obj) && depth === 1) {
25
+ try {
26
+ const contents = await fs.readFile(path.resolve(base, obj), "utf-8");
27
+ const data = fm(contents);
28
+ const attributes = await convert(
29
+ opts,
30
+ data.attributes,
31
+ base,
32
+ depth + 1
33
+ );
34
+ return {
35
+ attributes: {
36
+ ...attributes,
37
+ id: path.basename(obj)
38
+ },
39
+ body: data.body
40
+ };
41
+ } catch {
42
+ return obj;
43
+ }
44
+ }
45
+ return obj;
46
+ }
47
+ const entries = await Promise.all(
48
+ Object.entries(obj).map(async ([key, value]) => {
49
+ if (Array.isArray(value)) {
50
+ const values = await Promise.all(
51
+ value.map((item) => convert(opts, item, base))
52
+ );
53
+ return [key, values];
54
+ }
55
+ const v = await convert(opts, value, base);
56
+ return [key, v];
57
+ })
58
+ );
59
+ return entries.reduce((dict, curr) => {
60
+ return {
61
+ ...dict,
62
+ [curr[0]]: curr[1]
63
+ };
64
+ }, {});
65
+ }
66
+ function importDataPlugin(imagetools_plugin, { base = "./src/data" } = {}) {
67
+ const opts = {
68
+ /** @type {import('rollup').PluginContext | null} */
69
+ plugin_context: null,
70
+ /** @type {import('vite').ResolvedConfig | null} */
71
+ vite_config: null,
72
+ imagetools_plugin,
73
+ base
74
+ };
75
+ return {
76
+ name: "import-data",
77
+ enforce: "pre",
78
+ configResolved(config) {
79
+ opts.vite_config = config;
80
+ },
81
+ buildStart() {
82
+ opts.plugin_context = this;
83
+ },
84
+ async transform(src, id) {
85
+ var _a;
86
+ if (/\.(md)$/.test(id)) {
87
+ const base2 = path.resolve(((_a = opts.vite_config) == null ? void 0 : _a.root) ?? "", opts.base);
88
+ const d = fm(src);
89
+ const attributes = await convert(opts, d.attributes, base2);
90
+ return `export default ${JSON.stringify({
91
+ attributes,
92
+ body: d.body
93
+ })}`;
94
+ }
95
+ }
96
+ };
97
+ }
98
+ function plugin(imagePlugins) {
99
+ const enhancedImagesPlugin = imagePlugins.find(
100
+ (item) => item.name === "imagetools"
101
+ );
102
+ if (!enhancedImagesPlugin) {
103
+ throw new Error("Cannot find enhanced image plugin");
104
+ }
105
+ return [importDataPlugin(enhancedImagesPlugin), ...imagePlugins];
106
+ }
107
+ export {
108
+ plugin as default
109
+ };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "sveltekit-data-plugin",
3
+ "version": "1.0.0",
4
+ "author": {
5
+ "name": "Jonny Thaw",
6
+ "url": "https://jthaw.me"
7
+ },
8
+ "devDependencies": {
9
+ "standard-version": "^9.5.0",
10
+ "vite": "^6.2.2"
11
+ },
12
+ "peerDependencies": {
13
+ "@sveltejs/enhanced-img": "^0.4.4"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "main": "./dist/plugin.js",
19
+ "module": "./dist/plugin.mjs",
20
+ "exports": {
21
+ ".": {
22
+ "import": "./dist/plugin.mjs",
23
+ "require": "./dist/plugin.js"
24
+ }
25
+ },
26
+ "scripts": {
27
+ "build": "vite build",
28
+ "release": "npm run build && standard-version && npm publish"
29
+ },
30
+ "dependencies": {
31
+ "front-matter": "^4.0.2"
32
+ }
33
+ }