@drawbridge/drawbridge-utils 0.0.1 → 0.0.3

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 CHANGED
@@ -1,18 +1,39 @@
1
1
  # @drawbridge/drawbridge-utils
2
2
 
3
- Shared helper functions used across the drawbridge-* repositories.
3
+ Shared helpers and data used across the drawbridge-* repositories.
4
4
 
5
- ## Exports
5
+ ## Main entry
6
6
 
7
+ ```js
8
+ const utils = require( '@drawbridge/drawbridge-utils' );
9
+ // or: import { capitalize } from '@drawbridge/drawbridge-utils';
10
+ ```
11
+
12
+ Exports:
13
+
14
+ - `bytesToGB( bytes )` / `bytesToMB( bytes )` — byte conversion.
7
15
  - `capitalize( string )` — uppercases the first character.
8
- - `formatCurrency({ code, digits, display, locale, value })` Intl-based currency formatter. `display: 'standard'` (default) returns Intl's standard string; `'parts'` splits symbol/number for custom layouts.
9
- - `formatDateString({ date, locale, options })` — Intl-based date formatter.
16
+ - `constants` default record shape per Mongo collection name (action, brand, campaign, draw, member, organization, page, prize, range, referrer, template, usage, user).
17
+ - `currencies` / `currency( code )` — list of ISO currencies (key/value/code/digits) and lookup by code.
18
+ - `expiredPaymentMethod( card )` — checks if a card record's year/month is in the past.
19
+ - `formatCurrency({ code, digits, display, locale, value })` — Intl-based formatter. `display: 'standard'` (default) returns Intl's standard string; `'parts'` splits symbol/number for custom layouts.
20
+ - `formatDateString({ date, locale, time, options })` — Intl-based date formatter. `time: true` adds hour/minute.
10
21
  - `formatNumber( number, digits )` — Intl-based number formatter with fixed-digit min/max.
11
- - `getPlanFeature( plan, key )` — looks up a feature on a plan; returns `{ granted, message }`.
12
- - `regex` `{ url, protocols }` shared URL regex constants.
13
- - `shareUrls({ formUri, organization, page })` — builds page share URLs from the configured form base URI.
14
- - `urlRoot( string )` — `'https://'` if the input string contains `'https'`, else `'http://'`.
15
- - `infinite`, `isInfinite( value )`, `megabyte`, `gigabyte` — size-related constants.
22
+ - `getPlanFeature( plan, key )` — `{ granted, message }` lookup.
23
+ - `infinite`, `isInfinite( value )`, `megabyte`, `gigabyte` size constants.
24
+ - `percentage( a, b, decimals )` — `(a / b) * 100`, fixed decimals.
25
+ - `reducers.fields` — reducer for grouping fields by `additional` / `lead` type.
26
+ - `regex.url` / `regex.protocols` / `regex.domain` — shared regex constants.
27
+ - `shareUrls({ formUri, organization, page })` — builds share URLs from the configured form base URI. Falls back to `process.env.APP_CLIENT_FORM_URI` if `formUri` is not passed (server-only).
28
+ - `urlRoot( string )` — `'https://'` if input contains `'https'`, else `'http://'`.
29
+
30
+ ## Encrypt entry (server-only)
31
+
32
+ ```js
33
+ const { encrypt, decrypt } = require( '@drawbridge/drawbridge-utils/encrypt' );
34
+ ```
35
+
36
+ Server-only because it uses Node `crypto` and reads `process.env.ENCRYPTION_KEY`. Exposed as a sub-export so client bundles don't pull Node built-ins.
16
37
 
17
38
  ## Build & publish
18
39
 
@@ -22,4 +43,4 @@ npm install
22
43
  npm run build
23
44
  ```
24
45
 
25
- `build` runs `tsup` (dual CJS + ESM output) and then `npm publish`. Bump the `version` in `package.json` first.
46
+ `build` runs `tsup` (multi-entry, dual CJS + ESM output) and then `npm publish`. Bump `version` in `package.json` first.
@@ -0,0 +1,15 @@
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+ var __commonJS = (cb, mod) => function __require2() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+
12
+ export {
13
+ __require,
14
+ __commonJS
15
+ };
@@ -0,0 +1,46 @@
1
+ const crypto = require( 'crypto' );
2
+
3
+ const ALGORITHM = 'aes-256-gcm';
4
+
5
+ const getKey = () => Buffer.from( process.env.ENCRYPTION_KEY, 'hex' );
6
+
7
+ const encrypt = ( value ) => {
8
+
9
+ const iv = crypto.randomBytes( 12 );
10
+ const cipher = crypto.createCipheriv( ALGORITHM, getKey(), iv );
11
+ const data = Buffer.concat([
12
+ cipher.update( JSON.stringify( value ), 'utf8' ),
13
+ cipher.final()
14
+ ]);
15
+ const tag = cipher.getAuthTag();
16
+
17
+ return [ iv, tag, data ].map( ( b ) => b.toString( 'hex' ) ).join( ':' );
18
+
19
+ };
20
+
21
+ const decrypt = ( value ) => {
22
+
23
+ if( typeof value !== 'string' ) return value;
24
+
25
+ const [ ivHex, tagHex, dataHex ] = value.split( ':' );
26
+ const decipher = crypto.createDecipheriv(
27
+ ALGORITHM,
28
+ getKey(),
29
+ Buffer.from( ivHex, 'hex' )
30
+ );
31
+
32
+ decipher.setAuthTag( Buffer.from( tagHex, 'hex' ) );
33
+
34
+ const result = Buffer.concat([
35
+ decipher.update( Buffer.from( dataHex, 'hex' ) ),
36
+ decipher.final()
37
+ ]);
38
+
39
+ return JSON.parse( result.toString( 'utf8' ) );
40
+
41
+ };
42
+
43
+ module.exports = {
44
+ decrypt,
45
+ encrypt
46
+ };
@@ -0,0 +1,46 @@
1
+ const crypto = require( 'crypto' );
2
+
3
+ const ALGORITHM = 'aes-256-gcm';
4
+
5
+ const getKey = () => Buffer.from( process.env.ENCRYPTION_KEY, 'hex' );
6
+
7
+ const encrypt = ( value ) => {
8
+
9
+ const iv = crypto.randomBytes( 12 );
10
+ const cipher = crypto.createCipheriv( ALGORITHM, getKey(), iv );
11
+ const data = Buffer.concat([
12
+ cipher.update( JSON.stringify( value ), 'utf8' ),
13
+ cipher.final()
14
+ ]);
15
+ const tag = cipher.getAuthTag();
16
+
17
+ return [ iv, tag, data ].map( ( b ) => b.toString( 'hex' ) ).join( ':' );
18
+
19
+ };
20
+
21
+ const decrypt = ( value ) => {
22
+
23
+ if( typeof value !== 'string' ) return value;
24
+
25
+ const [ ivHex, tagHex, dataHex ] = value.split( ':' );
26
+ const decipher = crypto.createDecipheriv(
27
+ ALGORITHM,
28
+ getKey(),
29
+ Buffer.from( ivHex, 'hex' )
30
+ );
31
+
32
+ decipher.setAuthTag( Buffer.from( tagHex, 'hex' ) );
33
+
34
+ const result = Buffer.concat([
35
+ decipher.update( Buffer.from( dataHex, 'hex' ) ),
36
+ decipher.final()
37
+ ]);
38
+
39
+ return JSON.parse( result.toString( 'utf8' ) );
40
+
41
+ };
42
+
43
+ module.exports = {
44
+ decrypt,
45
+ encrypt
46
+ };
@@ -0,0 +1,33 @@
1
+ // encrypt.js
2
+ var crypto = require("crypto");
3
+ var ALGORITHM = "aes-256-gcm";
4
+ var getKey = () => Buffer.from(process.env.ENCRYPTION_KEY, "hex");
5
+ var encrypt = (value) => {
6
+ const iv = crypto.randomBytes(12);
7
+ const cipher = crypto.createCipheriv(ALGORITHM, getKey(), iv);
8
+ const data = Buffer.concat([
9
+ cipher.update(JSON.stringify(value), "utf8"),
10
+ cipher.final()
11
+ ]);
12
+ const tag = cipher.getAuthTag();
13
+ return [iv, tag, data].map((b) => b.toString("hex")).join(":");
14
+ };
15
+ var decrypt = (value) => {
16
+ if (typeof value !== "string") return value;
17
+ const [ivHex, tagHex, dataHex] = value.split(":");
18
+ const decipher = crypto.createDecipheriv(
19
+ ALGORITHM,
20
+ getKey(),
21
+ Buffer.from(ivHex, "hex")
22
+ );
23
+ decipher.setAuthTag(Buffer.from(tagHex, "hex"));
24
+ const result = Buffer.concat([
25
+ decipher.update(Buffer.from(dataHex, "hex")),
26
+ decipher.final()
27
+ ]);
28
+ return JSON.parse(result.toString("utf8"));
29
+ };
30
+ module.exports = {
31
+ decrypt,
32
+ encrypt
33
+ };
@@ -0,0 +1,43 @@
1
+ import {
2
+ __commonJS,
3
+ __require
4
+ } from "./chunk-EBO3CZXG.mjs";
5
+
6
+ // encrypt.js
7
+ var require_encrypt = __commonJS({
8
+ "encrypt.js"(exports, module) {
9
+ var crypto = __require("crypto");
10
+ var ALGORITHM = "aes-256-gcm";
11
+ var getKey = () => Buffer.from(process.env.ENCRYPTION_KEY, "hex");
12
+ var encrypt = (value) => {
13
+ const iv = crypto.randomBytes(12);
14
+ const cipher = crypto.createCipheriv(ALGORITHM, getKey(), iv);
15
+ const data = Buffer.concat([
16
+ cipher.update(JSON.stringify(value), "utf8"),
17
+ cipher.final()
18
+ ]);
19
+ const tag = cipher.getAuthTag();
20
+ return [iv, tag, data].map((b) => b.toString("hex")).join(":");
21
+ };
22
+ var decrypt = (value) => {
23
+ if (typeof value !== "string") return value;
24
+ const [ivHex, tagHex, dataHex] = value.split(":");
25
+ const decipher = crypto.createDecipheriv(
26
+ ALGORITHM,
27
+ getKey(),
28
+ Buffer.from(ivHex, "hex")
29
+ );
30
+ decipher.setAuthTag(Buffer.from(tagHex, "hex"));
31
+ const result = Buffer.concat([
32
+ decipher.update(Buffer.from(dataHex, "hex")),
33
+ decipher.final()
34
+ ]);
35
+ return JSON.parse(result.toString("utf8"));
36
+ };
37
+ module.exports = {
38
+ decrypt,
39
+ encrypt
40
+ };
41
+ }
42
+ });
43
+ export default require_encrypt();
package/dist/index.d.mts CHANGED
@@ -1,3 +1,7 @@
1
+ const { code, data } = require( 'currency-codes' );
2
+
3
+ const constants = require( './lib/constants' );
4
+
1
5
  const infinite = 1e300;
2
6
 
3
7
  const isInfinite = ( value ) => value === infinite;
@@ -7,12 +11,43 @@ const gigabyte = ( megabyte * 1024 );
7
11
 
8
12
  const urlRoot = ( string ) => ( string?.includes( 'https' ) ? 'https://' : 'http://' );
9
13
 
14
+ const bytesToGB = ( bytes ) => {
15
+
16
+ const divide = ( 1024 * 1024 * 1024 );
17
+
18
+ return bytes ? Number( bytes ) / divide : 0;
19
+
20
+ };
21
+
22
+ const bytesToMB = ( bytes ) => {
23
+
24
+ const divide = ( 1024 * 1024 );
25
+
26
+ return bytes ? Number( bytes ) / divide : 0;
27
+
28
+ };
29
+
10
30
  const capitalize = ( string ) => {
11
31
 
12
32
  return string?.charAt( 0 )?.toUpperCase() + string?.slice( 1 );
13
33
 
14
34
  };
15
35
 
36
+ const expiredPaymentMethod = ( card ) => {
37
+
38
+ const currentDate = new Date();
39
+ const year = currentDate.getFullYear();
40
+ const month = new Date().getMonth();
41
+
42
+ const expired = [
43
+ card?.year < year,
44
+ card?.year === year && card?.month <= month
45
+ ].filter( Boolean );
46
+
47
+ return Boolean( expired?.length );
48
+
49
+ };
50
+
16
51
  const formatCurrency = ({
17
52
  code = 'USD',
18
53
  digits = 2,
@@ -54,6 +89,7 @@ const formatCurrency = ({
54
89
  const formatDateString = ({
55
90
  date,
56
91
  locale,
92
+ time = false,
57
93
  options = {
58
94
  day : 'numeric',
59
95
  month : 'long',
@@ -62,9 +98,13 @@ const formatDateString = ({
62
98
  }
63
99
  }) => {
64
100
 
65
- return new Date( date ).toLocaleDateString(
101
+ const resolved = time
102
+ ? { ...options, hour : 'numeric', minute : '2-digit' }
103
+ : options;
104
+
105
+ return new Date( date ).toLocaleString(
66
106
  locale,
67
- options
107
+ resolved
68
108
  );
69
109
 
70
110
  };
@@ -94,9 +134,43 @@ const getPlanFeature = ( plan, key ) => {
94
134
 
95
135
  };
96
136
 
137
+ const percentage = ( value1, value2, decimals = 1 ) => ( ( ( ( value1 || 0 ) / ( value2 || 0 ) ) * 100 ) || 0 ).toFixed( decimals );
138
+
139
+ const reducers = {
140
+ fields : ( data = [], callback = () => ({}) ) => data.reduce(
141
+ ( accumulator, field ) => {
142
+
143
+ const type = field?.type;
144
+
145
+ if( ! accumulator[ type ] ) return accumulator;
146
+
147
+ accumulator[ type ].items.push({
148
+ ...field,
149
+ ...callback( field )
150
+ });
151
+
152
+ accumulator[ type ].keys.push( field?.slug );
153
+
154
+ return accumulator;
155
+
156
+ },
157
+ {
158
+ additional : {
159
+ items : [],
160
+ keys : []
161
+ },
162
+ lead : {
163
+ items : [],
164
+ keys : []
165
+ }
166
+ }
167
+ )
168
+ };
169
+
97
170
  const regex = {
98
- url : /^(https:\/\/)/,
99
- protocols : /^(https?:\/\/)?(www\.)?/
171
+ domain : /^([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/,
172
+ protocols : /^(https?:\/\/)?(www\.)?/,
173
+ url : /^(https:\/\/)/
100
174
  };
101
175
 
102
176
  const shareUrls = ({
@@ -105,8 +179,11 @@ const shareUrls = ({
105
179
  page
106
180
  }) => {
107
181
 
108
- const preface = urlRoot( formUri );
109
- const base = formUri;
182
+ const resolvedFormUri = formUri
183
+ || ( typeof process !== 'undefined' ? process.env?.APP_CLIENT_FORM_URI : undefined );
184
+
185
+ const preface = urlRoot( resolvedFormUri );
186
+ const base = resolvedFormUri;
110
187
 
111
188
  const qr = preface + base?.replace( preface, '' ) + '/' + page?.shortId + '?qr=1';
112
189
  const short = preface + base?.replace( preface, '' ) + '/' + page?.shortId;
@@ -147,8 +224,22 @@ const shareUrls = ({
147
224
 
148
225
  };
149
226
 
227
+ const currencies = data.map( ( item ) => ({
228
+ ...item,
229
+ key : item.currency,
230
+ value : item.code
231
+ }));
232
+
233
+ const currency = ( val ) => code( val );
234
+
150
235
  module.exports = {
236
+ bytesToGB,
237
+ bytesToMB,
151
238
  capitalize,
239
+ constants,
240
+ currencies,
241
+ currency,
242
+ expiredPaymentMethod,
152
243
  formatCurrency,
153
244
  formatDateString,
154
245
  formatNumber,
@@ -157,6 +248,8 @@ module.exports = {
157
248
  infinite,
158
249
  isInfinite,
159
250
  megabyte,
251
+ percentage,
252
+ reducers,
160
253
  regex,
161
254
  shareUrls,
162
255
  urlRoot
package/dist/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ const { code, data } = require( 'currency-codes' );
2
+
3
+ const constants = require( './lib/constants' );
4
+
1
5
  const infinite = 1e300;
2
6
 
3
7
  const isInfinite = ( value ) => value === infinite;
@@ -7,12 +11,43 @@ const gigabyte = ( megabyte * 1024 );
7
11
 
8
12
  const urlRoot = ( string ) => ( string?.includes( 'https' ) ? 'https://' : 'http://' );
9
13
 
14
+ const bytesToGB = ( bytes ) => {
15
+
16
+ const divide = ( 1024 * 1024 * 1024 );
17
+
18
+ return bytes ? Number( bytes ) / divide : 0;
19
+
20
+ };
21
+
22
+ const bytesToMB = ( bytes ) => {
23
+
24
+ const divide = ( 1024 * 1024 );
25
+
26
+ return bytes ? Number( bytes ) / divide : 0;
27
+
28
+ };
29
+
10
30
  const capitalize = ( string ) => {
11
31
 
12
32
  return string?.charAt( 0 )?.toUpperCase() + string?.slice( 1 );
13
33
 
14
34
  };
15
35
 
36
+ const expiredPaymentMethod = ( card ) => {
37
+
38
+ const currentDate = new Date();
39
+ const year = currentDate.getFullYear();
40
+ const month = new Date().getMonth();
41
+
42
+ const expired = [
43
+ card?.year < year,
44
+ card?.year === year && card?.month <= month
45
+ ].filter( Boolean );
46
+
47
+ return Boolean( expired?.length );
48
+
49
+ };
50
+
16
51
  const formatCurrency = ({
17
52
  code = 'USD',
18
53
  digits = 2,
@@ -54,6 +89,7 @@ const formatCurrency = ({
54
89
  const formatDateString = ({
55
90
  date,
56
91
  locale,
92
+ time = false,
57
93
  options = {
58
94
  day : 'numeric',
59
95
  month : 'long',
@@ -62,9 +98,13 @@ const formatDateString = ({
62
98
  }
63
99
  }) => {
64
100
 
65
- return new Date( date ).toLocaleDateString(
101
+ const resolved = time
102
+ ? { ...options, hour : 'numeric', minute : '2-digit' }
103
+ : options;
104
+
105
+ return new Date( date ).toLocaleString(
66
106
  locale,
67
- options
107
+ resolved
68
108
  );
69
109
 
70
110
  };
@@ -94,9 +134,43 @@ const getPlanFeature = ( plan, key ) => {
94
134
 
95
135
  };
96
136
 
137
+ const percentage = ( value1, value2, decimals = 1 ) => ( ( ( ( value1 || 0 ) / ( value2 || 0 ) ) * 100 ) || 0 ).toFixed( decimals );
138
+
139
+ const reducers = {
140
+ fields : ( data = [], callback = () => ({}) ) => data.reduce(
141
+ ( accumulator, field ) => {
142
+
143
+ const type = field?.type;
144
+
145
+ if( ! accumulator[ type ] ) return accumulator;
146
+
147
+ accumulator[ type ].items.push({
148
+ ...field,
149
+ ...callback( field )
150
+ });
151
+
152
+ accumulator[ type ].keys.push( field?.slug );
153
+
154
+ return accumulator;
155
+
156
+ },
157
+ {
158
+ additional : {
159
+ items : [],
160
+ keys : []
161
+ },
162
+ lead : {
163
+ items : [],
164
+ keys : []
165
+ }
166
+ }
167
+ )
168
+ };
169
+
97
170
  const regex = {
98
- url : /^(https:\/\/)/,
99
- protocols : /^(https?:\/\/)?(www\.)?/
171
+ domain : /^([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/,
172
+ protocols : /^(https?:\/\/)?(www\.)?/,
173
+ url : /^(https:\/\/)/
100
174
  };
101
175
 
102
176
  const shareUrls = ({
@@ -105,8 +179,11 @@ const shareUrls = ({
105
179
  page
106
180
  }) => {
107
181
 
108
- const preface = urlRoot( formUri );
109
- const base = formUri;
182
+ const resolvedFormUri = formUri
183
+ || ( typeof process !== 'undefined' ? process.env?.APP_CLIENT_FORM_URI : undefined );
184
+
185
+ const preface = urlRoot( resolvedFormUri );
186
+ const base = resolvedFormUri;
110
187
 
111
188
  const qr = preface + base?.replace( preface, '' ) + '/' + page?.shortId + '?qr=1';
112
189
  const short = preface + base?.replace( preface, '' ) + '/' + page?.shortId;
@@ -147,8 +224,22 @@ const shareUrls = ({
147
224
 
148
225
  };
149
226
 
227
+ const currencies = data.map( ( item ) => ({
228
+ ...item,
229
+ key : item.currency,
230
+ value : item.code
231
+ }));
232
+
233
+ const currency = ( val ) => code( val );
234
+
150
235
  module.exports = {
236
+ bytesToGB,
237
+ bytesToMB,
151
238
  capitalize,
239
+ constants,
240
+ currencies,
241
+ currency,
242
+ expiredPaymentMethod,
152
243
  formatCurrency,
153
244
  formatDateString,
154
245
  formatNumber,
@@ -157,6 +248,8 @@ module.exports = {
157
248
  infinite,
158
249
  isInfinite,
159
250
  megabyte,
251
+ percentage,
252
+ reducers,
160
253
  regex,
161
254
  shareUrls,
162
255
  urlRoot
package/dist/index.js CHANGED
@@ -1,15 +1,219 @@
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __commonJS = (cb, mod) => function __require() {
3
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
4
+ };
5
+
6
+ // lib/constants.js
7
+ var require_constants = __commonJS({
8
+ "lib/constants.js"(exports2, module2) {
9
+ var font = {
10
+ family: "Roboto Flex",
11
+ transform: "none",
12
+ weight: "regular"
13
+ };
14
+ module2.exports = {
15
+ action: {
16
+ usage: {
17
+ actions: 0
18
+ }
19
+ },
20
+ brand: {
21
+ style: {
22
+ body: font,
23
+ heading: font
24
+ },
25
+ totals: {
26
+ campaigns: 0
27
+ }
28
+ },
29
+ campaign: {
30
+ agreements: {
31
+ marketing: {
32
+ enabled: false,
33
+ label: "I agree to the marketing terms and conditions",
34
+ link: null
35
+ },
36
+ terms: {
37
+ enabled: false,
38
+ label: "I agree to the terms and conditions",
39
+ link: null
40
+ }
41
+ },
42
+ defaults: {
43
+ active: "Enter",
44
+ confirmation: "Submission was successful",
45
+ inactive: "Submissions are closed",
46
+ email: "You were selected"
47
+ },
48
+ notifications: {
49
+ draw: {
50
+ subject: "You have been selected",
51
+ body: "Thanks for being part of our giveaway"
52
+ }
53
+ },
54
+ settings: {
55
+ submissionLeadPrimaryKey: "email",
56
+ submissionEntryMaximum: 1,
57
+ submissionEntryFilter: "campaign",
58
+ submissionEntryHighscore: false,
59
+ submissionEntryLimit: 1
60
+ },
61
+ status: "drafted",
62
+ totals: {
63
+ advertisements: 0,
64
+ affiliates: 0,
65
+ draws: 0,
66
+ exports: 0,
67
+ entries: 0,
68
+ fields: 2,
69
+ integrations: 1,
70
+ leads: 0,
71
+ links: 0,
72
+ pages: 0,
73
+ prizes: 0,
74
+ ranges: 0,
75
+ submissions: 0
76
+ },
77
+ type: "giveaway"
78
+ },
79
+ draw: {
80
+ status: "qualified",
81
+ totals: {
82
+ notifications: 0
83
+ }
84
+ },
85
+ member: {
86
+ status: "pending"
87
+ },
88
+ organization: {
89
+ errors: [],
90
+ totals: {
91
+ affiliates: 0,
92
+ brands: 0,
93
+ campaigns: 0,
94
+ leads: 0,
95
+ draws: 0,
96
+ entries: 0,
97
+ invitations: 0,
98
+ invoices: 0,
99
+ members: 0,
100
+ ranges: 0,
101
+ pages: 0,
102
+ prizes: 0,
103
+ storage: 0,
104
+ submissions: 0,
105
+ subscriptions: 0,
106
+ usage: 0
107
+ }
108
+ },
109
+ page: {
110
+ domains: [],
111
+ status: "drafted",
112
+ totals: {
113
+ leads: 0,
114
+ entries: 0,
115
+ submissions: 0
116
+ }
117
+ },
118
+ prize: {
119
+ inventory: 0,
120
+ remaining: 0,
121
+ shipping: false,
122
+ status: "drafted",
123
+ totals: {
124
+ draws: 0
125
+ }
126
+ },
127
+ range: {
128
+ totals: {
129
+ leads: 0,
130
+ entries: 0,
131
+ submissions: 0
132
+ }
133
+ },
134
+ referrer: {
135
+ totals: {
136
+ originizations: 0,
137
+ subscriptions: 0,
138
+ users: 0
139
+ }
140
+ },
141
+ template: {
142
+ page: {
143
+ style: {
144
+ body: font,
145
+ heading: font
146
+ }
147
+ }
148
+ },
149
+ usage: {
150
+ totals: {
151
+ actions: 0,
152
+ affiliates: 0,
153
+ brands: 0,
154
+ campaigns: 0,
155
+ connections: 0,
156
+ entries: 0,
157
+ files: 0,
158
+ members: 0,
159
+ orders: 0,
160
+ pages: 0,
161
+ revenue: 0,
162
+ storage: 0,
163
+ submissions: 0,
164
+ workflows: 0
165
+ }
166
+ },
167
+ user: {
168
+ access: {
169
+ ai: false
170
+ },
171
+ image: null,
172
+ totals: {
173
+ inbox: 0,
174
+ invitations: 0,
175
+ messages: 0,
176
+ methods: 0,
177
+ organizations: 1,
178
+ teams: 0
179
+ }
180
+ }
181
+ };
182
+ }
183
+ });
184
+
1
185
  // index.js
186
+ var { code, data } = require("currency-codes");
187
+ var constants = require_constants();
2
188
  var infinite = 1e300;
3
189
  var isInfinite = (value) => value === infinite;
4
190
  var megabyte = 1024 * 1024;
5
191
  var gigabyte = megabyte * 1024;
6
192
  var urlRoot = (string) => (string == null ? void 0 : string.includes("https")) ? "https://" : "http://";
193
+ var bytesToGB = (bytes) => {
194
+ const divide = 1024 * 1024 * 1024;
195
+ return bytes ? Number(bytes) / divide : 0;
196
+ };
197
+ var bytesToMB = (bytes) => {
198
+ const divide = 1024 * 1024;
199
+ return bytes ? Number(bytes) / divide : 0;
200
+ };
7
201
  var capitalize = (string) => {
8
202
  var _a;
9
203
  return ((_a = string == null ? void 0 : string.charAt(0)) == null ? void 0 : _a.toUpperCase()) + (string == null ? void 0 : string.slice(1));
10
204
  };
205
+ var expiredPaymentMethod = (card) => {
206
+ const currentDate = /* @__PURE__ */ new Date();
207
+ const year = currentDate.getFullYear();
208
+ const month = (/* @__PURE__ */ new Date()).getMonth();
209
+ const expired = [
210
+ (card == null ? void 0 : card.year) < year,
211
+ (card == null ? void 0 : card.year) === year && (card == null ? void 0 : card.month) <= month
212
+ ].filter(Boolean);
213
+ return Boolean(expired == null ? void 0 : expired.length);
214
+ };
11
215
  var formatCurrency = ({
12
- code = "USD",
216
+ code: code2 = "USD",
13
217
  digits = 2,
14
218
  display = "standard",
15
219
  locale,
@@ -18,7 +222,7 @@ var formatCurrency = ({
18
222
  var _a;
19
223
  const resolvedLocale = locale || (typeof navigator !== "undefined" ? navigator == null ? void 0 : navigator.language : null) || "en-US";
20
224
  const options = {
21
- currency: code,
225
+ currency: code2,
22
226
  minimumFractionDigits: digits,
23
227
  maximumFractionDigits: digits,
24
228
  style: "currency"
@@ -28,7 +232,7 @@ var formatCurrency = ({
28
232
  const parts = new Intl.NumberFormat(resolvedLocale, options).formatToParts(value);
29
233
  const symbol = ((_a = parts.find((p) => p.type === "currency")) == null ? void 0 : _a.value) || "";
30
234
  const number = parts.filter((p) => p.type !== "currency" && p.type !== "literal").map((p) => p.value).join("");
31
- return symbol + number + " " + code;
235
+ return symbol + number + " " + code2;
32
236
  }
33
237
  ;
34
238
  return new Intl.NumberFormat(resolvedLocale, options).format(value);
@@ -36,6 +240,7 @@ var formatCurrency = ({
36
240
  var formatDateString = ({
37
241
  date,
38
242
  locale,
243
+ time = false,
39
244
  options = {
40
245
  day: "numeric",
41
246
  month: "long",
@@ -43,9 +248,10 @@ var formatDateString = ({
43
248
  year: "numeric"
44
249
  }
45
250
  }) => {
46
- return new Date(date).toLocaleDateString(
251
+ const resolved = time ? { ...options, hour: "numeric", minute: "2-digit" } : options;
252
+ return new Date(date).toLocaleString(
47
253
  locale,
48
- options
254
+ resolved
49
255
  );
50
256
  };
51
257
  var formatNumber = (number, digits = 0) => {
@@ -64,17 +270,45 @@ var getPlanFeature = (plan, key) => {
64
270
  message: granted ? feature : error
65
271
  };
66
272
  };
273
+ var percentage = (value1, value2, decimals = 1) => ((value1 || 0) / (value2 || 0) * 100 || 0).toFixed(decimals);
274
+ var reducers = {
275
+ fields: (data2 = [], callback = () => ({})) => data2.reduce(
276
+ (accumulator, field) => {
277
+ const type = field == null ? void 0 : field.type;
278
+ if (!accumulator[type]) return accumulator;
279
+ accumulator[type].items.push({
280
+ ...field,
281
+ ...callback(field)
282
+ });
283
+ accumulator[type].keys.push(field == null ? void 0 : field.slug);
284
+ return accumulator;
285
+ },
286
+ {
287
+ additional: {
288
+ items: [],
289
+ keys: []
290
+ },
291
+ lead: {
292
+ items: [],
293
+ keys: []
294
+ }
295
+ }
296
+ )
297
+ };
67
298
  var regex = {
68
- url: /^(https:\/\/)/,
69
- protocols: /^(https?:\/\/)?(www\.)?/
299
+ domain: /^([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/,
300
+ protocols: /^(https?:\/\/)?(www\.)?/,
301
+ url: /^(https:\/\/)/
70
302
  };
71
303
  var shareUrls = ({
72
304
  formUri,
73
305
  organization,
74
306
  page
75
307
  }) => {
76
- const preface = urlRoot(formUri);
77
- const base = formUri;
308
+ var _a;
309
+ const resolvedFormUri = formUri || (typeof process !== "undefined" ? (_a = process.env) == null ? void 0 : _a.APP_CLIENT_FORM_URI : void 0);
310
+ const preface = urlRoot(resolvedFormUri);
311
+ const base = resolvedFormUri;
78
312
  const qr = preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId) + "?qr=1";
79
313
  const short = preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId);
80
314
  const url = preface + (organization == null ? void 0 : organization.subdomain) + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.slug);
@@ -107,8 +341,20 @@ var shareUrls = ({
107
341
  urls
108
342
  };
109
343
  };
344
+ var currencies = data.map((item) => ({
345
+ ...item,
346
+ key: item.currency,
347
+ value: item.code
348
+ }));
349
+ var currency = (val) => code(val);
110
350
  module.exports = {
351
+ bytesToGB,
352
+ bytesToMB,
111
353
  capitalize,
354
+ constants,
355
+ currencies,
356
+ currency,
357
+ expiredPaymentMethod,
112
358
  formatCurrency,
113
359
  formatDateString,
114
360
  formatNumber,
@@ -117,6 +363,8 @@ module.exports = {
117
363
  infinite,
118
364
  isInfinite,
119
365
  megabyte,
366
+ percentage,
367
+ reducers,
120
368
  regex,
121
369
  shareUrls,
122
370
  urlRoot
package/dist/index.mjs CHANGED
@@ -1,22 +1,221 @@
1
- var __getOwnPropNames = Object.getOwnPropertyNames;
2
- var __commonJS = (cb, mod) => function __require() {
3
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
4
- };
1
+ import {
2
+ __commonJS,
3
+ __require
4
+ } from "./chunk-EBO3CZXG.mjs";
5
+
6
+ // lib/constants.js
7
+ var require_constants = __commonJS({
8
+ "lib/constants.js"(exports, module) {
9
+ var font = {
10
+ family: "Roboto Flex",
11
+ transform: "none",
12
+ weight: "regular"
13
+ };
14
+ module.exports = {
15
+ action: {
16
+ usage: {
17
+ actions: 0
18
+ }
19
+ },
20
+ brand: {
21
+ style: {
22
+ body: font,
23
+ heading: font
24
+ },
25
+ totals: {
26
+ campaigns: 0
27
+ }
28
+ },
29
+ campaign: {
30
+ agreements: {
31
+ marketing: {
32
+ enabled: false,
33
+ label: "I agree to the marketing terms and conditions",
34
+ link: null
35
+ },
36
+ terms: {
37
+ enabled: false,
38
+ label: "I agree to the terms and conditions",
39
+ link: null
40
+ }
41
+ },
42
+ defaults: {
43
+ active: "Enter",
44
+ confirmation: "Submission was successful",
45
+ inactive: "Submissions are closed",
46
+ email: "You were selected"
47
+ },
48
+ notifications: {
49
+ draw: {
50
+ subject: "You have been selected",
51
+ body: "Thanks for being part of our giveaway"
52
+ }
53
+ },
54
+ settings: {
55
+ submissionLeadPrimaryKey: "email",
56
+ submissionEntryMaximum: 1,
57
+ submissionEntryFilter: "campaign",
58
+ submissionEntryHighscore: false,
59
+ submissionEntryLimit: 1
60
+ },
61
+ status: "drafted",
62
+ totals: {
63
+ advertisements: 0,
64
+ affiliates: 0,
65
+ draws: 0,
66
+ exports: 0,
67
+ entries: 0,
68
+ fields: 2,
69
+ integrations: 1,
70
+ leads: 0,
71
+ links: 0,
72
+ pages: 0,
73
+ prizes: 0,
74
+ ranges: 0,
75
+ submissions: 0
76
+ },
77
+ type: "giveaway"
78
+ },
79
+ draw: {
80
+ status: "qualified",
81
+ totals: {
82
+ notifications: 0
83
+ }
84
+ },
85
+ member: {
86
+ status: "pending"
87
+ },
88
+ organization: {
89
+ errors: [],
90
+ totals: {
91
+ affiliates: 0,
92
+ brands: 0,
93
+ campaigns: 0,
94
+ leads: 0,
95
+ draws: 0,
96
+ entries: 0,
97
+ invitations: 0,
98
+ invoices: 0,
99
+ members: 0,
100
+ ranges: 0,
101
+ pages: 0,
102
+ prizes: 0,
103
+ storage: 0,
104
+ submissions: 0,
105
+ subscriptions: 0,
106
+ usage: 0
107
+ }
108
+ },
109
+ page: {
110
+ domains: [],
111
+ status: "drafted",
112
+ totals: {
113
+ leads: 0,
114
+ entries: 0,
115
+ submissions: 0
116
+ }
117
+ },
118
+ prize: {
119
+ inventory: 0,
120
+ remaining: 0,
121
+ shipping: false,
122
+ status: "drafted",
123
+ totals: {
124
+ draws: 0
125
+ }
126
+ },
127
+ range: {
128
+ totals: {
129
+ leads: 0,
130
+ entries: 0,
131
+ submissions: 0
132
+ }
133
+ },
134
+ referrer: {
135
+ totals: {
136
+ originizations: 0,
137
+ subscriptions: 0,
138
+ users: 0
139
+ }
140
+ },
141
+ template: {
142
+ page: {
143
+ style: {
144
+ body: font,
145
+ heading: font
146
+ }
147
+ }
148
+ },
149
+ usage: {
150
+ totals: {
151
+ actions: 0,
152
+ affiliates: 0,
153
+ brands: 0,
154
+ campaigns: 0,
155
+ connections: 0,
156
+ entries: 0,
157
+ files: 0,
158
+ members: 0,
159
+ orders: 0,
160
+ pages: 0,
161
+ revenue: 0,
162
+ storage: 0,
163
+ submissions: 0,
164
+ workflows: 0
165
+ }
166
+ },
167
+ user: {
168
+ access: {
169
+ ai: false
170
+ },
171
+ image: null,
172
+ totals: {
173
+ inbox: 0,
174
+ invitations: 0,
175
+ messages: 0,
176
+ methods: 0,
177
+ organizations: 1,
178
+ teams: 0
179
+ }
180
+ }
181
+ };
182
+ }
183
+ });
5
184
 
6
185
  // index.js
7
186
  var require_index = __commonJS({
8
187
  "index.js"(exports, module) {
188
+ var { code, data } = __require("currency-codes");
189
+ var constants = require_constants();
9
190
  var infinite = 1e300;
10
191
  var isInfinite = (value) => value === infinite;
11
192
  var megabyte = 1024 * 1024;
12
193
  var gigabyte = megabyte * 1024;
13
194
  var urlRoot = (string) => (string == null ? void 0 : string.includes("https")) ? "https://" : "http://";
195
+ var bytesToGB = (bytes) => {
196
+ const divide = 1024 * 1024 * 1024;
197
+ return bytes ? Number(bytes) / divide : 0;
198
+ };
199
+ var bytesToMB = (bytes) => {
200
+ const divide = 1024 * 1024;
201
+ return bytes ? Number(bytes) / divide : 0;
202
+ };
14
203
  var capitalize = (string) => {
15
204
  var _a;
16
205
  return ((_a = string == null ? void 0 : string.charAt(0)) == null ? void 0 : _a.toUpperCase()) + (string == null ? void 0 : string.slice(1));
17
206
  };
207
+ var expiredPaymentMethod = (card) => {
208
+ const currentDate = /* @__PURE__ */ new Date();
209
+ const year = currentDate.getFullYear();
210
+ const month = (/* @__PURE__ */ new Date()).getMonth();
211
+ const expired = [
212
+ (card == null ? void 0 : card.year) < year,
213
+ (card == null ? void 0 : card.year) === year && (card == null ? void 0 : card.month) <= month
214
+ ].filter(Boolean);
215
+ return Boolean(expired == null ? void 0 : expired.length);
216
+ };
18
217
  var formatCurrency = ({
19
- code = "USD",
218
+ code: code2 = "USD",
20
219
  digits = 2,
21
220
  display = "standard",
22
221
  locale,
@@ -25,7 +224,7 @@ var require_index = __commonJS({
25
224
  var _a;
26
225
  const resolvedLocale = locale || (typeof navigator !== "undefined" ? navigator == null ? void 0 : navigator.language : null) || "en-US";
27
226
  const options = {
28
- currency: code,
227
+ currency: code2,
29
228
  minimumFractionDigits: digits,
30
229
  maximumFractionDigits: digits,
31
230
  style: "currency"
@@ -35,7 +234,7 @@ var require_index = __commonJS({
35
234
  const parts = new Intl.NumberFormat(resolvedLocale, options).formatToParts(value);
36
235
  const symbol = ((_a = parts.find((p) => p.type === "currency")) == null ? void 0 : _a.value) || "";
37
236
  const number = parts.filter((p) => p.type !== "currency" && p.type !== "literal").map((p) => p.value).join("");
38
- return symbol + number + " " + code;
237
+ return symbol + number + " " + code2;
39
238
  }
40
239
  ;
41
240
  return new Intl.NumberFormat(resolvedLocale, options).format(value);
@@ -43,6 +242,7 @@ var require_index = __commonJS({
43
242
  var formatDateString = ({
44
243
  date,
45
244
  locale,
245
+ time = false,
46
246
  options = {
47
247
  day: "numeric",
48
248
  month: "long",
@@ -50,9 +250,10 @@ var require_index = __commonJS({
50
250
  year: "numeric"
51
251
  }
52
252
  }) => {
53
- return new Date(date).toLocaleDateString(
253
+ const resolved = time ? { ...options, hour: "numeric", minute: "2-digit" } : options;
254
+ return new Date(date).toLocaleString(
54
255
  locale,
55
- options
256
+ resolved
56
257
  );
57
258
  };
58
259
  var formatNumber = (number, digits = 0) => {
@@ -71,17 +272,45 @@ var require_index = __commonJS({
71
272
  message: granted ? feature : error
72
273
  };
73
274
  };
275
+ var percentage = (value1, value2, decimals = 1) => ((value1 || 0) / (value2 || 0) * 100 || 0).toFixed(decimals);
276
+ var reducers = {
277
+ fields: (data2 = [], callback = () => ({})) => data2.reduce(
278
+ (accumulator, field) => {
279
+ const type = field == null ? void 0 : field.type;
280
+ if (!accumulator[type]) return accumulator;
281
+ accumulator[type].items.push({
282
+ ...field,
283
+ ...callback(field)
284
+ });
285
+ accumulator[type].keys.push(field == null ? void 0 : field.slug);
286
+ return accumulator;
287
+ },
288
+ {
289
+ additional: {
290
+ items: [],
291
+ keys: []
292
+ },
293
+ lead: {
294
+ items: [],
295
+ keys: []
296
+ }
297
+ }
298
+ )
299
+ };
74
300
  var regex = {
75
- url: /^(https:\/\/)/,
76
- protocols: /^(https?:\/\/)?(www\.)?/
301
+ domain: /^([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/,
302
+ protocols: /^(https?:\/\/)?(www\.)?/,
303
+ url: /^(https:\/\/)/
77
304
  };
78
305
  var shareUrls = ({
79
306
  formUri,
80
307
  organization,
81
308
  page
82
309
  }) => {
83
- const preface = urlRoot(formUri);
84
- const base = formUri;
310
+ var _a;
311
+ const resolvedFormUri = formUri || (typeof process !== "undefined" ? (_a = process.env) == null ? void 0 : _a.APP_CLIENT_FORM_URI : void 0);
312
+ const preface = urlRoot(resolvedFormUri);
313
+ const base = resolvedFormUri;
85
314
  const qr = preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId) + "?qr=1";
86
315
  const short = preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId);
87
316
  const url = preface + (organization == null ? void 0 : organization.subdomain) + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.slug);
@@ -114,8 +343,20 @@ var require_index = __commonJS({
114
343
  urls
115
344
  };
116
345
  };
346
+ var currencies = data.map((item) => ({
347
+ ...item,
348
+ key: item.currency,
349
+ value: item.code
350
+ }));
351
+ var currency = (val) => code(val);
117
352
  module.exports = {
353
+ bytesToGB,
354
+ bytesToMB,
118
355
  capitalize,
356
+ constants,
357
+ currencies,
358
+ currency,
359
+ expiredPaymentMethod,
119
360
  formatCurrency,
120
361
  formatDateString,
121
362
  formatNumber,
@@ -124,6 +365,8 @@ var require_index = __commonJS({
124
365
  infinite,
125
366
  isInfinite,
126
367
  megabyte,
368
+ percentage,
369
+ reducers,
127
370
  regex,
128
371
  shareUrls,
129
372
  urlRoot
package/package.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "dependencies": {
3
+ "currency-codes": "2.2.0",
3
4
  "tsup": "8.5.1",
4
5
  "typescript": "5.9.3"
5
6
  },
@@ -8,6 +9,11 @@
8
9
  "types": "./dist/index.d.ts",
9
10
  "import": "./dist/index.mjs",
10
11
  "require": "./dist/index.js"
12
+ },
13
+ "./encrypt": {
14
+ "types": "./dist/encrypt.d.ts",
15
+ "import": "./dist/encrypt.mjs",
16
+ "require": "./dist/encrypt.js"
11
17
  }
12
18
  },
13
19
  "files": [
@@ -21,8 +27,8 @@
21
27
  "access": "public"
22
28
  },
23
29
  "scripts": {
24
- "build": "tsup ./index.js && npm publish"
30
+ "build": "tsup && npm publish"
25
31
  },
26
32
  "types": "dist/index.d.ts",
27
- "version": "0.0.1"
33
+ "version": "0.0.3"
28
34
  }