@scalemule/news-publication 0.0.7

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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +74 -0
  3. package/cookie-consent.css +419 -0
  4. package/dist/chunk-C7JTEHTH.js +158 -0
  5. package/dist/chunk-GB36YM56.js +72 -0
  6. package/dist/chunk-PYCU2T5O.js +93 -0
  7. package/dist/chunk-R33MJWND.js +261 -0
  8. package/dist/chunk-TJ7RL3PV.js +252 -0
  9. package/dist/chunk-YQXS2KQI.js +112 -0
  10. package/dist/cookie-consent-banner.cjs +210 -0
  11. package/dist/cookie-consent-banner.d.cts +19 -0
  12. package/dist/cookie-consent-banner.d.ts +19 -0
  13. package/dist/cookie-consent-banner.js +3 -0
  14. package/dist/cookie-settings-view.cjs +470 -0
  15. package/dist/cookie-settings-view.d.cts +15 -0
  16. package/dist/cookie-settings-view.d.ts +15 -0
  17. package/dist/cookie-settings-view.js +3 -0
  18. package/dist/index.cjs +1460 -0
  19. package/dist/index.d.cts +317 -0
  20. package/dist/index.d.ts +317 -0
  21. package/dist/index.js +441 -0
  22. package/dist/marketplace-Ch7mdJZv.d.cts +123 -0
  23. package/dist/marketplace-Ch7mdJZv.d.ts +123 -0
  24. package/dist/marketplace-forms.cjs +134 -0
  25. package/dist/marketplace-forms.d.cts +10 -0
  26. package/dist/marketplace-forms.d.ts +10 -0
  27. package/dist/marketplace-forms.js +115 -0
  28. package/dist/marketplace-view.cjs +110 -0
  29. package/dist/marketplace-view.d.cts +21 -0
  30. package/dist/marketplace-view.d.ts +21 -0
  31. package/dist/marketplace-view.js +85 -0
  32. package/dist/meet-5Ym5bxfh.d.cts +79 -0
  33. package/dist/meet-5Ym5bxfh.d.ts +79 -0
  34. package/dist/meet-forms.cjs +188 -0
  35. package/dist/meet-forms.d.cts +13 -0
  36. package/dist/meet-forms.d.ts +13 -0
  37. package/dist/meet-forms.js +166 -0
  38. package/dist/meet-view.cjs +82 -0
  39. package/dist/meet-view.d.cts +23 -0
  40. package/dist/meet-view.d.ts +23 -0
  41. package/dist/meet-view.js +59 -0
  42. package/dist/snapshot-BS4hn1dk.d.cts +234 -0
  43. package/dist/snapshot-BS4hn1dk.d.ts +234 -0
  44. package/dist/snapshot-file.cjs +192 -0
  45. package/dist/snapshot-file.d.cts +21 -0
  46. package/dist/snapshot-file.d.ts +21 -0
  47. package/dist/snapshot-file.js +38 -0
  48. package/marketplace.css +61 -0
  49. package/package.json +103 -0
  50. package/tokens/broadsheet.css +61 -0
@@ -0,0 +1,112 @@
1
+ // src/marketplace.ts
2
+ var JOB_EMPLOYMENT_TYPES = [
3
+ { value: "full_time", label: "Full-time" },
4
+ { value: "part_time", label: "Part-time" },
5
+ { value: "contract", label: "Contract" },
6
+ { value: "temporary", label: "Temporary" },
7
+ { value: "internship", label: "Internship" }
8
+ ];
9
+ var CLASSIFIED_CATEGORIES = [
10
+ { value: "for-sale", label: "For sale" },
11
+ { value: "services", label: "Services" },
12
+ { value: "housing", label: "Housing" },
13
+ { value: "community", label: "Community" },
14
+ { value: "wanted", label: "Wanted" }
15
+ ];
16
+ function clipChars(value, max) {
17
+ const chars = Array.from(value.trim());
18
+ return chars.length <= max ? chars.join("") : chars.slice(0, max).join("");
19
+ }
20
+ function isEmploymentType(value) {
21
+ return JOB_EMPLOYMENT_TYPES.some((item) => item.value === value);
22
+ }
23
+ function isClassifiedCategory(value) {
24
+ return CLASSIFIED_CATEGORIES.some((item) => item.value === value);
25
+ }
26
+ function employmentLabel(value) {
27
+ return JOB_EMPLOYMENT_TYPES.find((item) => item.value === value)?.label ?? "";
28
+ }
29
+ function categoryLabel(value) {
30
+ return CLASSIFIED_CATEGORIES.find((item) => item.value === value)?.label ?? "";
31
+ }
32
+ function publicJobsPath(query = "") {
33
+ const params = new URLSearchParams({ limit: "50" });
34
+ const q = clipChars(query, 80);
35
+ if (q) params.set("q", q);
36
+ return `/v1/jobs/openings/public/postings?${params}`;
37
+ }
38
+ function publicJobPath(slug) {
39
+ return `/v1/jobs/openings/public/postings/${encodeURIComponent(slug)}`;
40
+ }
41
+ function classifiedSearchPath(options = {}) {
42
+ const params = new URLSearchParams({ status: "active", limit: "50", sort_by: "newest" });
43
+ const query = clipChars(options.query ?? "", 80);
44
+ if (query) params.set("query", query);
45
+ if (options.category && isClassifiedCategory(options.category)) params.set("category", options.category);
46
+ return `/v1/listings/search?${params}`;
47
+ }
48
+ function classifiedPath(id) {
49
+ return `/v1/listings/${encodeURIComponent(id)}`;
50
+ }
51
+ function requireText(value, label, max, min = 1) {
52
+ const text = clipChars(typeof value === "string" ? value : "", max);
53
+ if (Array.from(text).length < min) throw new Error(`Please complete the ${label}.`);
54
+ return text;
55
+ }
56
+ function prepareJobPost(input, towns) {
57
+ const title = requireText(input.title, "job title", 120);
58
+ const company = requireText(input.company, "employer", 120);
59
+ const town = requireText(input.town, "town", 80);
60
+ const description = requireText(input.description, "description", 4e3, 20);
61
+ const employment = typeof input.employment_type === "string" ? input.employment_type : "";
62
+ if (!towns.includes(town)) throw new Error("Please choose a town this paper covers.");
63
+ if (!isEmploymentType(employment)) throw new Error("Please choose a job type.");
64
+ const email = clipChars(typeof input.apply_email === "string" ? input.apply_email : "", 254);
65
+ if (email && !/^[^\s@]+@[^\s@]+$/.test(email)) throw new Error("Please check the apply email.");
66
+ return { title, company, town, employment_type: employment, description, apply_email: email || void 0 };
67
+ }
68
+ function jobEmployerBody(job) {
69
+ return { company_name: job.company, headline: `${job.company} in ${job.town}` };
70
+ }
71
+ function jobOpeningBody(job) {
72
+ const apply = job.apply_email ? `
73
+ Apply: ${job.apply_email}` : "";
74
+ return {
75
+ title: job.title,
76
+ employment_type: job.employment_type,
77
+ location_type: "onsite",
78
+ description_md: `${job.description}
79
+
80
+ Town: ${job.town}${apply}`
81
+ };
82
+ }
83
+ function jobPostingBody(job) {
84
+ return { channel: "partner_board", title_override: job.title, body_md: job.description, language: "en" };
85
+ }
86
+ function prepareClassified(input, towns, region, now = /* @__PURE__ */ new Date()) {
87
+ const title = requireText(input.title, "title", 120);
88
+ const description = requireText(input.description, "description", 4e3, 20);
89
+ const town = requireText(input.town, "town", 80);
90
+ const category = typeof input.category === "string" ? input.category : "";
91
+ if (!towns.includes(town)) throw new Error("Please choose a town this paper covers.");
92
+ if (!isClassifiedCategory(category)) throw new Error("Please choose a category.");
93
+ let price;
94
+ if (input.price !== void 0 && input.price !== "" && input.price !== null) {
95
+ const parsed = Number(input.price);
96
+ if (!Number.isInteger(parsed) || parsed < 0 || parsed > 1e6) throw new Error("Please check the price.");
97
+ price = parsed;
98
+ }
99
+ const expires = new Date(now);
100
+ expires.setUTCDate(expires.getUTCDate() + 30);
101
+ return {
102
+ title,
103
+ description,
104
+ category,
105
+ price,
106
+ currency: "USD",
107
+ location: { town, region },
108
+ expires_at: expires.toISOString()
109
+ };
110
+ }
111
+
112
+ export { CLASSIFIED_CATEGORIES, JOB_EMPLOYMENT_TYPES, categoryLabel, classifiedPath, classifiedSearchPath, clipChars, employmentLabel, isClassifiedCategory, isEmploymentType, jobEmployerBody, jobOpeningBody, jobPostingBody, prepareClassified, prepareJobPost, publicJobPath, publicJobsPath };
@@ -0,0 +1,210 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('react');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ // src/cookies.ts
8
+ var COOKIE_CONSENT_KEY = "sm_cookie_consent_v1";
9
+ var COOKIE_CONSENT_BACKUP_KEY = "napsite_cookie_consent_v1";
10
+ var COOKIE_CONSENT_EVENT = "scalemule-cookie-consent-change";
11
+ var COOKIE_CONSENT_MAX_AGE_SECONDS = 365 * 24 * 60 * 60;
12
+ var DEFAULT_PREFERENCES_REJECTED = {
13
+ performance: false,
14
+ functional: false,
15
+ advertising: false
16
+ };
17
+ var DEFAULT_PREFERENCES_ACCEPTED = {
18
+ performance: true,
19
+ functional: true,
20
+ advertising: true
21
+ };
22
+ var memoryConsent = null;
23
+ function readCookie(name) {
24
+ if (typeof document === "undefined") return null;
25
+ const match = document.cookie.match(new RegExp("(?:^|; )" + name.replace(/([.$?*|{}()[\]\\/+^])/g, "\\$1") + "=([^;]*)"));
26
+ return match ? decodeURIComponent(match[1]) : null;
27
+ }
28
+ function writeCookie(name, value, maxAgeSeconds) {
29
+ if (typeof document === "undefined") return;
30
+ const secure = typeof location !== "undefined" && location.protocol === "https:" ? "; Secure" : "";
31
+ document.cookie = `${name}=${encodeURIComponent(value)}; Path=/; Max-Age=${maxAgeSeconds}; SameSite=Lax${secure}`;
32
+ }
33
+ function getCookieConsent() {
34
+ if (typeof window === "undefined") return memoryConsent;
35
+ try {
36
+ const raw = readCookie(COOKIE_CONSENT_KEY) || readCookie(COOKIE_CONSENT_BACKUP_KEY);
37
+ if (raw) {
38
+ const parsed = JSON.parse(raw);
39
+ if (parsed && parsed.version === 1 && parsed.preferences) {
40
+ memoryConsent = parsed;
41
+ return parsed;
42
+ }
43
+ }
44
+ const stored = window.localStorage?.getItem(COOKIE_CONSENT_KEY);
45
+ if (stored) {
46
+ const parsed = JSON.parse(stored);
47
+ if (parsed && parsed.version === 1 && parsed.preferences) {
48
+ memoryConsent = parsed;
49
+ return parsed;
50
+ }
51
+ }
52
+ } catch {
53
+ }
54
+ return memoryConsent;
55
+ }
56
+ function hasConsented() {
57
+ return getCookieConsent() !== null;
58
+ }
59
+ function setCookieConsent(preferences, source = "settings_save") {
60
+ const mergedPreferences = {
61
+ essential: true,
62
+ performance: Boolean(preferences.performance),
63
+ functional: Boolean(preferences.functional),
64
+ advertising: Boolean(preferences.advertising)
65
+ };
66
+ let anonymous_id;
67
+ if (typeof window !== "undefined") {
68
+ try {
69
+ anonymous_id = window.localStorage?.getItem("napsite_visitor_v1") || void 0;
70
+ } catch {
71
+ }
72
+ }
73
+ const record = {
74
+ version: 1,
75
+ preferences: mergedPreferences,
76
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
77
+ anonymous_id,
78
+ source
79
+ };
80
+ memoryConsent = record;
81
+ const serialized = JSON.stringify(record);
82
+ writeCookie(COOKIE_CONSENT_KEY, serialized, COOKIE_CONSENT_MAX_AGE_SECONDS);
83
+ writeCookie(COOKIE_CONSENT_BACKUP_KEY, serialized, COOKIE_CONSENT_MAX_AGE_SECONDS);
84
+ if (typeof window !== "undefined") {
85
+ try {
86
+ window.localStorage?.setItem(COOKIE_CONSENT_KEY, serialized);
87
+ } catch {
88
+ }
89
+ window.dispatchEvent(new CustomEvent(COOKIE_CONSENT_EVENT, { detail: record }));
90
+ }
91
+ return record;
92
+ }
93
+ function acceptAllCookies() {
94
+ return setCookieConsent(DEFAULT_PREFERENCES_ACCEPTED, "banner_accept");
95
+ }
96
+ function rejectOptionalCookies() {
97
+ return setCookieConsent(DEFAULT_PREFERENCES_REJECTED, "banner_reject");
98
+ }
99
+ async function recordConsentToCompliance(record, options) {
100
+ if (typeof window === "undefined") return;
101
+ const endpoint = options?.endpoint || "/api/compliance/consent";
102
+ try {
103
+ const payload = {
104
+ consent_type: "cookie_policy",
105
+ granted: record.preferences.performance || record.preferences.advertising,
106
+ preferences: record.preferences,
107
+ source: record.source,
108
+ anonymous_id: record.anonymous_id,
109
+ timestamp: record.timestamp,
110
+ url: window.location.href,
111
+ user_agent: window.navigator.userAgent
112
+ };
113
+ if (typeof navigator.sendBeacon === "function") {
114
+ navigator.sendBeacon(endpoint, new Blob([JSON.stringify(payload)], { type: "application/json" }));
115
+ } else {
116
+ await fetch(endpoint, {
117
+ method: "POST",
118
+ headers: { "content-type": "application/json" },
119
+ body: JSON.stringify(payload),
120
+ keepalive: true
121
+ });
122
+ }
123
+ } catch {
124
+ }
125
+ }
126
+ function CookieConsentBanner({
127
+ title = "Help Us Improve Our Website with Cookies",
128
+ text,
129
+ settingsUrl = "/cookies",
130
+ className = "",
131
+ publicationSlug,
132
+ complianceEndpoint = "/api/compliance/consent"
133
+ }) {
134
+ const [mounted, setMounted] = react.useState(false);
135
+ const [visible, setVisible] = react.useState(false);
136
+ react.useEffect(() => {
137
+ setMounted(true);
138
+ if (!hasConsented()) {
139
+ const timer = window.setTimeout(() => setVisible(true), 300);
140
+ return () => window.clearTimeout(timer);
141
+ }
142
+ const onConsentChange = () => {
143
+ if (hasConsented()) {
144
+ setVisible(false);
145
+ }
146
+ };
147
+ window.addEventListener(COOKIE_CONSENT_EVENT, onConsentChange);
148
+ return () => window.removeEventListener(COOKIE_CONSENT_EVENT, onConsentChange);
149
+ }, []);
150
+ if (!mounted || !visible) return null;
151
+ const handleAccept = () => {
152
+ const record = acceptAllCookies();
153
+ setVisible(false);
154
+ void recordConsentToCompliance(record, {
155
+ endpoint: complianceEndpoint});
156
+ };
157
+ const handleReject = () => {
158
+ const record = rejectOptionalCookies();
159
+ setVisible(false);
160
+ void recordConsentToCompliance(record, {
161
+ endpoint: complianceEndpoint});
162
+ };
163
+ const defaultText = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
164
+ "We use cookies and process data from your device to analyze website performance, personalize ad content, and improve your experience. Your consent includes data transfers outside of the country you\u2019re located. View",
165
+ " ",
166
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: settingsUrl, className: "sm-cookie-banner-link", children: "Cookie Settings" }),
167
+ " ",
168
+ "for more information."
169
+ ] });
170
+ return /* @__PURE__ */ jsxRuntime.jsx(
171
+ "aside",
172
+ {
173
+ className: `sm-cookie-banner-wrapper ${className}`,
174
+ role: "region",
175
+ "aria-label": "Cookie consent",
176
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sm-cookie-banner-card", children: [
177
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sm-cookie-banner-content", children: [
178
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "sm-cookie-banner-title", children: title }),
179
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "sm-cookie-banner-text", children: text ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
180
+ text,
181
+ " ",
182
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: settingsUrl, className: "sm-cookie-banner-link", children: "Cookie Settings" })
183
+ ] }) : defaultText })
184
+ ] }),
185
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sm-cookie-banner-actions", children: [
186
+ /* @__PURE__ */ jsxRuntime.jsx(
187
+ "button",
188
+ {
189
+ type: "button",
190
+ className: "sm-cookie-btn sm-cookie-btn-primary",
191
+ onClick: handleAccept,
192
+ children: "Accept"
193
+ }
194
+ ),
195
+ /* @__PURE__ */ jsxRuntime.jsx(
196
+ "button",
197
+ {
198
+ type: "button",
199
+ className: "sm-cookie-btn sm-cookie-btn-secondary",
200
+ onClick: handleReject,
201
+ children: "Reject"
202
+ }
203
+ )
204
+ ] })
205
+ ] })
206
+ }
207
+ );
208
+ }
209
+
210
+ exports.CookieConsentBanner = CookieConsentBanner;
@@ -0,0 +1,19 @@
1
+ import react__default from 'react';
2
+
3
+ interface CookieConsentBannerProps {
4
+ /** Title displayed in banner. Default: "Help Us Improve Our Website with Cookies" */
5
+ title?: string;
6
+ /** Description text displayed in banner */
7
+ text?: string;
8
+ /** URL to the detailed cookie settings page. Default: "/cookies" */
9
+ settingsUrl?: string;
10
+ /** Custom class name on outermost wrapper */
11
+ className?: string;
12
+ /** Optional publication identifier or slug for compliance reporting */
13
+ publicationSlug?: string;
14
+ /** Compliance recording endpoint. Default: "/api/compliance/consent" */
15
+ complianceEndpoint?: string;
16
+ }
17
+ declare function CookieConsentBanner({ title, text, settingsUrl, className, publicationSlug, complianceEndpoint, }: CookieConsentBannerProps): react__default.JSX.Element | null;
18
+
19
+ export { CookieConsentBanner, type CookieConsentBannerProps };
@@ -0,0 +1,19 @@
1
+ import react__default from 'react';
2
+
3
+ interface CookieConsentBannerProps {
4
+ /** Title displayed in banner. Default: "Help Us Improve Our Website with Cookies" */
5
+ title?: string;
6
+ /** Description text displayed in banner */
7
+ text?: string;
8
+ /** URL to the detailed cookie settings page. Default: "/cookies" */
9
+ settingsUrl?: string;
10
+ /** Custom class name on outermost wrapper */
11
+ className?: string;
12
+ /** Optional publication identifier or slug for compliance reporting */
13
+ publicationSlug?: string;
14
+ /** Compliance recording endpoint. Default: "/api/compliance/consent" */
15
+ complianceEndpoint?: string;
16
+ }
17
+ declare function CookieConsentBanner({ title, text, settingsUrl, className, publicationSlug, complianceEndpoint, }: CookieConsentBannerProps): react__default.JSX.Element | null;
18
+
19
+ export { CookieConsentBanner, type CookieConsentBannerProps };
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ export { CookieConsentBanner } from './chunk-PYCU2T5O.js';
3
+ import './chunk-TJ7RL3PV.js';