@premiate/strapi-plugin-maplibre-field 1.2.0 → 1.2.2

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 (48) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/_chunks/{index-Dzpog-Qf.mjs → index-B0Nr95wz.mjs} +2 -2
  3. package/dist/_chunks/{index-Bp7DLorc.mjs → index-CBxydRKp.mjs} +1 -1
  4. package/dist/_chunks/{index-zNvHsRuo.js → index-CDY4Awnh.js} +1 -1
  5. package/dist/_chunks/{index-DjK7O741.js → index-ysvid6md.js} +2 -2
  6. package/dist/admin/de-B0QBc7M2.js +27 -0
  7. package/dist/admin/de-BMK0skCB.mjs +27 -0
  8. package/dist/admin/en-C8iInpNv.mjs +27 -0
  9. package/dist/admin/en-CA0XtbN7.js +27 -0
  10. package/dist/admin/es-BU6JgkbZ.js +25 -0
  11. package/dist/admin/es-DZO4NHjt.mjs +25 -0
  12. package/dist/admin/fr-B8NDboqe.mjs +27 -0
  13. package/dist/admin/fr-DIBfzRbg.js +27 -0
  14. package/dist/admin/index-B-3vqPUe.mjs +1836 -0
  15. package/dist/admin/index-B0LVK-NK.js +170 -0
  16. package/dist/admin/index-BaGweGhM.js +1856 -0
  17. package/dist/admin/index-DjL4deZ6.mjs +171 -0
  18. package/dist/admin/index.js +3 -2
  19. package/dist/admin/index.mjs +1 -1
  20. package/dist/admin/it-B-lr3jhh.js +27 -0
  21. package/dist/admin/it-DFH6n6E1.mjs +27 -0
  22. package/dist/server/index.js +8 -3
  23. package/dist/server/index.mjs +6 -2
  24. package/dist/server/src/index.d.ts +9 -4
  25. package/package.json +12 -9
  26. package/dist/admin/src/components/Initializer.d.ts +0 -6
  27. package/dist/admin/src/components/MapInput/SearchBox.d.ts +0 -22
  28. package/dist/admin/src/components/MapInput/basemap-control.d.ts +0 -8
  29. package/dist/admin/src/components/MapInput/index.d.ts +0 -19
  30. package/dist/admin/src/components/MapInput/layer-control.d.ts +0 -18
  31. package/dist/admin/src/components/PluginIcon.d.ts +0 -2
  32. package/dist/admin/src/hooks/usePluginConfig.d.ts +0 -2
  33. package/dist/admin/src/mutations/mutateEditViewHook.d.ts +0 -30
  34. package/dist/admin/src/services/geocoder-service.d.ts +0 -31
  35. package/dist/admin/src/services/poi-service.d.ts +0 -160
  36. package/dist/admin/src/utils/getTrad.d.ts +0 -2
  37. package/dist/admin/src/utils/pluginId.d.ts +0 -2
  38. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +0 -3
  39. package/dist/server/src/bootstrap.d.ts +0 -2
  40. package/dist/server/src/config/index.d.ts +0 -62
  41. package/dist/server/src/config/schema.d.ts +0 -53
  42. package/dist/server/src/controllers/config.d.ts +0 -9
  43. package/dist/server/src/controllers/index.d.ts +0 -10
  44. package/dist/server/src/destroy.d.ts +0 -2
  45. package/dist/server/src/register.d.ts +0 -5
  46. package/dist/server/src/routes/admin.d.ts +0 -12
  47. package/dist/server/src/routes/index.d.ts +0 -14
  48. package/dist/server/src/types/config.d.ts +0 -26
@@ -0,0 +1,171 @@
1
+ import { useRef, useEffect } from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { PinMap } from "@strapi/icons";
4
+ import { Flex } from "@strapi/design-system";
5
+ import { styled } from "styled-components";
6
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
7
+ const v = glob[path];
8
+ if (v) {
9
+ return typeof v === "function" ? v() : Promise.resolve(v);
10
+ }
11
+ return new Promise((_, reject) => {
12
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
13
+ reject.bind(
14
+ null,
15
+ new Error(
16
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
17
+ )
18
+ )
19
+ );
20
+ });
21
+ };
22
+ const name$1 = "@premiate/strapi-plugin-maplibre-field";
23
+ const strapi = { "name": "maplibre-field" };
24
+ const pluginPkg = {
25
+ name: name$1,
26
+ strapi
27
+ };
28
+ const pluginId = pluginPkg.name.replace(/^(@[^/]+\/)?strapi-plugin-/i, "");
29
+ const getTrad = (id) => `${pluginId}.${id}`;
30
+ const Initializer = ({ setPlugin }) => {
31
+ const ref = useRef(false);
32
+ useEffect(() => {
33
+ if (!ref.current) {
34
+ setPlugin("maplibre-field");
35
+ ref.current = true;
36
+ }
37
+ }, [setPlugin]);
38
+ return null;
39
+ };
40
+ const IconBox = styled(Flex)`
41
+ /* Hard code color values */
42
+ /* to stay consistent between themes */
43
+ background-color: #f0f0ff; /* primary100 */
44
+ border: 1px solid #d9d8ff; /* primary200 */
45
+
46
+ svg > path {
47
+ fill: #4945ff; /* primary600 */
48
+ }
49
+ `;
50
+ const PluginIcon = () => {
51
+ return /* @__PURE__ */ jsx(IconBox, { justifyContent: "center", alignItems: "center", width: 7, height: 6, hasRadius: true, "aria-hidden": true, children: /* @__PURE__ */ jsx(PinMap, {}) });
52
+ };
53
+ const mutateLayouts = (layouts) => {
54
+ return layouts.map((row) => {
55
+ return row.map((field) => {
56
+ const hasMapFieldEnabled = field.attribute?.pluginOptions?.["maplibre-field"]?.enabled;
57
+ if (!hasMapFieldEnabled) {
58
+ return field;
59
+ }
60
+ return {
61
+ ...field,
62
+ size: 12,
63
+ // Full width (12 columns out of 12)
64
+ attribute: {
65
+ ...field.attribute,
66
+ customField: `plugin::${pluginId}.map`
67
+ }
68
+ };
69
+ });
70
+ });
71
+ };
72
+ const mutateEditViewHook = (editLayout) => {
73
+ if (!editLayout) {
74
+ return editLayout;
75
+ }
76
+ if (!Array.isArray(editLayout.layout)) {
77
+ return editLayout;
78
+ }
79
+ const mutatedLayout = mutateLayouts(editLayout.layout);
80
+ return {
81
+ ...editLayout,
82
+ layout: mutatedLayout
83
+ };
84
+ };
85
+ const prefixPluginTranslations = (trad, pluginId2) => {
86
+ if (!pluginId2) {
87
+ throw new TypeError("pluginId can't be empty");
88
+ }
89
+ return Object.keys(trad).reduce((acc, current) => {
90
+ acc[`${pluginId2}.${current}`] = trad[current];
91
+ return acc;
92
+ }, {});
93
+ };
94
+ const name = pluginPkg.strapi.name;
95
+ const index = {
96
+ register(app) {
97
+ app.customFields.register({
98
+ name: "map",
99
+ pluginId,
100
+ type: "json",
101
+ intlLabel: {
102
+ id: getTrad("label"),
103
+ defaultMessage: "Map"
104
+ },
105
+ intlDescription: {
106
+ id: getTrad("description"),
107
+ defaultMessage: "A map custom field using MapLibre"
108
+ },
109
+ icon: PluginIcon,
110
+ components: {
111
+ Input: async () => import(
112
+ /* webpackChunkName: "input-component" */
113
+ "./index-B-3vqPUe.mjs"
114
+ )
115
+ },
116
+ options: {
117
+ advanced: [
118
+ {
119
+ sectionTitle: null,
120
+ items: [
121
+ {
122
+ name: "options.pluginOptions.i18n.localized",
123
+ type: "checkbox",
124
+ intlLabel: {
125
+ id: getTrad("i18n.localized.label"),
126
+ defaultMessage: "Enable localization for this field"
127
+ },
128
+ intlDescription: {
129
+ id: getTrad("i18n.localized.description"),
130
+ defaultMessage: "The field can have different values in each language"
131
+ },
132
+ defaultValue: false
133
+ }
134
+ ]
135
+ }
136
+ ]
137
+ }
138
+ });
139
+ app.registerPlugin({
140
+ id: pluginId,
141
+ initializer: Initializer,
142
+ isReady: false,
143
+ name
144
+ });
145
+ },
146
+ bootstrap(app) {
147
+ app.registerHook("Admin/CM/pages/EditView/mutate-edit-view-layout", mutateEditViewHook);
148
+ },
149
+ async registerTrads({ locales }) {
150
+ const importedTrads = await Promise.all(
151
+ locales.map((locale) => {
152
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("./de-BMK0skCB.mjs"), "./translations/en.json": () => import("./en-C8iInpNv.mjs"), "./translations/es.json": () => import("./es-DZO4NHjt.mjs"), "./translations/fr.json": () => import("./fr-B8NDboqe.mjs"), "./translations/it.json": () => import("./it-DFH6n6E1.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
153
+ return {
154
+ data: prefixPluginTranslations(data, pluginId),
155
+ locale
156
+ };
157
+ }).catch(() => {
158
+ return {
159
+ data: {},
160
+ locale
161
+ };
162
+ });
163
+ })
164
+ );
165
+ return Promise.resolve(importedTrads);
166
+ }
167
+ };
168
+ export {
169
+ getTrad as g,
170
+ index as i
171
+ };
@@ -1,3 +1,4 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-zNvHsRuo.js");
3
- module.exports = index.index;
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const index = require("./index-B0LVK-NK.js");
4
+ exports.default = index.index;
@@ -1,4 +1,4 @@
1
- import { i } from "../_chunks/index-Bp7DLorc.mjs";
1
+ import { i } from "./index-DjL4deZ6.mjs";
2
2
  export {
3
3
  i as default
4
4
  };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const label = "Mappa";
4
+ const description = "Un custom field per mappe usando MapLibre";
5
+ const search = "Cerca un indirizzo o luogo su OpenStreetMap";
6
+ const it = {
7
+ label,
8
+ description,
9
+ search,
10
+ "search.placeholder": "Cerca una località...",
11
+ "search.button": "Cerca",
12
+ "fields.address": "Indirizzo",
13
+ "fields.longitude": "Longitudine",
14
+ "fields.latitude": "Latitudine",
15
+ "fields.poi-name": "Nome POI",
16
+ "fields.poi-address": "Indirizzo completo",
17
+ "coordinates-saved": "Coordinate impostate",
18
+ "geocoding.success": "Indirizzo aggiornato con successo",
19
+ "geocoding.error": "Impossibile recuperare l'indirizzo. Riprova.",
20
+ "geocoding.no-results": "Nessun indirizzo trovato per questa posizione",
21
+ "i18n.localized.label": "Abilita la localizzazione per questo campo",
22
+ "i18n.localized.description": "Il campo può avere valori diversi in ogni lingua"
23
+ };
24
+ exports.default = it;
25
+ exports.description = description;
26
+ exports.label = label;
27
+ exports.search = search;
@@ -0,0 +1,27 @@
1
+ const label = "Mappa";
2
+ const description = "Un custom field per mappe usando MapLibre";
3
+ const search = "Cerca un indirizzo o luogo su OpenStreetMap";
4
+ const it = {
5
+ label,
6
+ description,
7
+ search,
8
+ "search.placeholder": "Cerca una località...",
9
+ "search.button": "Cerca",
10
+ "fields.address": "Indirizzo",
11
+ "fields.longitude": "Longitudine",
12
+ "fields.latitude": "Latitudine",
13
+ "fields.poi-name": "Nome POI",
14
+ "fields.poi-address": "Indirizzo completo",
15
+ "coordinates-saved": "Coordinate impostate",
16
+ "geocoding.success": "Indirizzo aggiornato con successo",
17
+ "geocoding.error": "Impossibile recuperare l'indirizzo. Riprova.",
18
+ "geocoding.no-results": "Nessun indirizzo trovato per questa posizione",
19
+ "i18n.localized.label": "Abilita la localizzazione per questo campo",
20
+ "i18n.localized.description": "Il campo può avere valori diversi in ogni lingua"
21
+ };
22
+ export {
23
+ it as default,
24
+ description,
25
+ label,
26
+ search
27
+ };
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
2
3
  const register = ({ strapi }) => {
3
4
  strapi.customFields.register({
4
5
  name: "map",
@@ -63,6 +64,11 @@ const schema = {
63
64
  type: "number",
64
65
  default: 5,
65
66
  description: "Snap radius in meters for double-click POI detection (default: 5m)"
67
+ },
68
+ useFullscreenPseudo: {
69
+ type: "boolean",
70
+ default: true,
71
+ description: "Use CSS-based fullscreen (faster on some devices) instead of native fullscreen API (requires MapLibre v5.18.0+)"
66
72
  }
67
73
  };
68
74
  function validator(config2) {
@@ -150,8 +156,7 @@ const admin = {
150
156
  path: "/config",
151
157
  handler: "config.getConfig",
152
158
  config: {
153
- auth: false
154
- // Config must be accessible from frontend to initialize the map
159
+ policies: ["admin::isAuthenticatedAdmin"]
155
160
  }
156
161
  }
157
162
  ]
@@ -167,4 +172,4 @@ const index = {
167
172
  controllers,
168
173
  routes
169
174
  };
170
- module.exports = index;
175
+ exports.default = index;
@@ -62,6 +62,11 @@ const schema = {
62
62
  type: "number",
63
63
  default: 5,
64
64
  description: "Snap radius in meters for double-click POI detection (default: 5m)"
65
+ },
66
+ useFullscreenPseudo: {
67
+ type: "boolean",
68
+ default: true,
69
+ description: "Use CSS-based fullscreen (faster on some devices) instead of native fullscreen API (requires MapLibre v5.18.0+)"
65
70
  }
66
71
  };
67
72
  function validator(config2) {
@@ -149,8 +154,7 @@ const admin = {
149
154
  path: "/config",
150
155
  handler: "config.getConfig",
151
156
  config: {
152
- auth: false
153
- // Config must be accessible from frontend to initialize the map
157
+ policies: ["admin::isAuthenticatedAdmin"]
154
158
  }
155
159
  }
156
160
  ]
@@ -1,6 +1,6 @@
1
1
  declare const _default: {
2
2
  register: ({ strapi }: {
3
- strapi: import("@strapi/types/dist/core").Strapi;
3
+ strapi: import('@strapi/types/dist/core').Strapi;
4
4
  }) => void;
5
5
  bootstrap: () => void;
6
6
  destroy: () => void;
@@ -56,12 +56,17 @@ declare const _default: {
56
56
  default: number;
57
57
  description: string;
58
58
  };
59
+ useFullscreenPseudo: {
60
+ type: string;
61
+ default: boolean;
62
+ description: string;
63
+ };
59
64
  };
60
- validator: (config: import("./types/config").MapLibreConfig) => void;
65
+ validator: (config: import('./types/config').MapLibreConfig) => void;
61
66
  };
62
67
  controllers: {
63
68
  config: ({ strapi }: {
64
- strapi: import("@strapi/types/dist/core").Strapi;
69
+ strapi: import('@strapi/types/dist/core').Strapi;
65
70
  }) => {
66
71
  getConfig(ctx: {
67
72
  body: unknown;
@@ -76,7 +81,7 @@ declare const _default: {
76
81
  path: string;
77
82
  handler: string;
78
83
  config: {
79
- auth: boolean;
84
+ policies: string[];
80
85
  };
81
86
  }[];
82
87
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@premiate/strapi-plugin-maplibre-field",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Strapi plugin that provides a MapLibre custom field",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,6 +23,7 @@
23
23
  "CHANGELOG.md",
24
24
  "logo.png"
25
25
  ],
26
+ "types": "./dist/server/src/index.d.ts",
26
27
  "exports": {
27
28
  "./package.json": "./package.json",
28
29
  "./strapi-admin": {
@@ -52,22 +53,21 @@
52
53
  "prepublishOnly": "npm run build && npm run verify && npm test"
53
54
  },
54
55
  "dependencies": {
55
- "maplibre-gl": "5.16.0",
56
- "pmtiles": "^4.3.2",
56
+ "maplibre-gl": "^5.21.0",
57
+ "pmtiles": "^4.4.0",
57
58
  "react-map-gl": "^8.1.0"
58
59
  },
59
60
  "devDependencies": {
60
- "@strapi/eslint-config": "^1.0.1",
61
- "@strapi/sdk-plugin": "^5.4.0",
61
+ "@strapi/sdk-plugin": "^6.0.1",
62
62
  "@strapi/typescript-utils": "^5.0.0",
63
63
  "@testing-library/jest-dom": "^6.0.0",
64
64
  "@testing-library/react": "^14.0.0",
65
65
  "@types/jest": "^30.0.0",
66
66
  "@types/react": "^18.0.0",
67
67
  "@types/react-dom": "^18.0.0",
68
- "@typescript-eslint/eslint-plugin": "^6.0.0",
69
- "@typescript-eslint/parser": "^6.0.0",
70
- "eslint": "^8.0.0",
68
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
69
+ "@typescript-eslint/parser": "^7.0.0",
70
+ "eslint": "^8.57.0",
71
71
  "eslint-config-prettier": "^10.1.8",
72
72
  "eslint-plugin-prettier": "^5.5.5",
73
73
  "identity-obj-proxy": "^3.0.0",
@@ -75,7 +75,7 @@
75
75
  "jest-environment-jsdom": "^30.2.0",
76
76
  "ts-jest": "^29.0.0",
77
77
  "ts-node": "^10.9.2",
78
- "typescript": "^5.0.0"
78
+ "typescript": "^5.5.0"
79
79
  },
80
80
  "author": {
81
81
  "name": "Claudio Bernardini",
@@ -95,6 +95,9 @@
95
95
  "access": "public",
96
96
  "registry": "https://registry.npmjs.org/"
97
97
  },
98
+ "overrides": {
99
+ "@microsoft/api-extractor": "7.56.3"
100
+ },
98
101
  "engines": {
99
102
  "node": ">=20.0.0 <=24.x.x",
100
103
  "npm": ">=6.0.0"
@@ -1,6 +0,0 @@
1
- /// <reference types="react" />
2
- interface InitializerProps {
3
- setPlugin: (id: string) => void;
4
- }
5
- declare const Initializer: React.FC<InitializerProps>;
6
- export default Initializer;
@@ -1,22 +0,0 @@
1
- /**
2
- * SearchBox Component
3
- *
4
- * Provides a search interface for geocoding (Nominatim) and custom POI search.
5
- * Displays results in a dropdown and calls onSelectResult when user selects a location.
6
- */
7
- import React from 'react';
8
- import type { LocationFeature } from '../../services/poi-service';
9
- export interface SearchBoxProps {
10
- onSelectResult: (result: LocationFeature) => void;
11
- nominatimUrl: string;
12
- poiSearchEnabled?: boolean;
13
- poiSources?: Array<{
14
- id: string;
15
- name: string;
16
- apiUrl: string;
17
- enabled?: boolean;
18
- color?: string;
19
- }>;
20
- }
21
- declare const SearchBox: React.FC<SearchBoxProps>;
22
- export default SearchBox;
@@ -1,8 +0,0 @@
1
- import type { MapStyle } from '../../../../server/src/types/config';
2
- interface BasemapControlProps {
3
- mapStyles: MapStyle[];
4
- currentStyleUrl: string;
5
- onStyleChange: (styleUrl: string) => void;
6
- }
7
- export default function BasemapControlComponent({ mapStyles, currentStyleUrl, onStyleChange, }: BasemapControlProps): null;
8
- export {};
@@ -1,19 +0,0 @@
1
- import React from 'react';
2
- import 'maplibre-gl/dist/maplibre-gl.css';
3
- interface MapFieldProps {
4
- intlLabel: {
5
- id: string;
6
- defaultMessage: string;
7
- };
8
- name: string;
9
- onChange: (event: {
10
- target: {
11
- name: string;
12
- value: string;
13
- type: string;
14
- };
15
- }) => void;
16
- value: string | null;
17
- }
18
- declare const MapField: React.FC<MapFieldProps>;
19
- export default MapField;
@@ -1,18 +0,0 @@
1
- import React from 'react';
2
- import type { MapRef } from 'react-map-gl/maplibre';
3
- export interface LayerConfig {
4
- id: string;
5
- name: string;
6
- enabled: boolean;
7
- color?: string;
8
- }
9
- interface LayerControlProps {
10
- mapRef: React.RefObject<MapRef>;
11
- layers: LayerConfig[];
12
- onLayerToggle: (layerId: string, enabled: boolean) => void;
13
- }
14
- /**
15
- * React wrapper for MapLibre Layer Control
16
- */
17
- declare const LayerControl: React.FC<LayerControlProps>;
18
- export default LayerControl;
@@ -1,2 +0,0 @@
1
- declare const PluginIcon: () => import("react/jsx-runtime").JSX.Element;
2
- export default PluginIcon;
@@ -1,2 +0,0 @@
1
- import type { MapLibreConfig } from '../../../server/src/types/config';
2
- export declare const usePluginConfig: () => MapLibreConfig;
@@ -1,30 +0,0 @@
1
- interface EditFieldLayout {
2
- attribute?: {
3
- customField?: string;
4
- pluginOptions?: {
5
- [key: string]: {
6
- enabled?: boolean;
7
- };
8
- };
9
- type?: string;
10
- };
11
- name?: string;
12
- size?: number;
13
- [key: string]: unknown;
14
- }
15
- interface EditLayout {
16
- layout: Array<Array<EditFieldLayout>>;
17
- components: {
18
- [uid: string]: {
19
- layout: Array<EditFieldLayout>;
20
- settings: unknown;
21
- };
22
- };
23
- metadatas: {
24
- [key: string]: unknown;
25
- };
26
- options: unknown;
27
- settings: unknown;
28
- }
29
- declare const mutateEditViewHook: (editLayout: EditLayout) => EditLayout;
30
- export default mutateEditViewHook;
@@ -1,31 +0,0 @@
1
- /**
2
- * Geocoder Service
3
- *
4
- * Combines Nominatim geocoding and custom POI search into a unified search interface
5
- */
6
- import type { LocationFeature } from './poi-service';
7
- export interface SearchResult {
8
- id: string;
9
- place_name: string;
10
- feature: LocationFeature;
11
- source: 'nominatim' | 'custom';
12
- }
13
- export interface POISource {
14
- id: string;
15
- name: string;
16
- apiUrl: string;
17
- enabled?: boolean;
18
- color?: string;
19
- }
20
- export interface SearchConfig {
21
- nominatimUrl: string;
22
- poiSearchEnabled?: boolean;
23
- poiSources?: POISource[];
24
- }
25
- /**
26
- * Perform unified search across Nominatim and custom POI sources
27
- * @param query Search query string
28
- * @param config Search configuration
29
- * @returns Array of search results
30
- */
31
- export declare function performSearch(query: string, config: SearchConfig): Promise<SearchResult[]>;