@drawbridge/drawbridge-utils 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.
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # @drawbridge/drawbridge-utils
2
+
3
+ Shared helper functions used across the drawbridge-* repositories.
4
+
5
+ ## Exports
6
+
7
+ - `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.
10
+ - `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.
16
+
17
+ ## Build & publish
18
+
19
+ ```bash
20
+ nvm use
21
+ npm install
22
+ npm run build
23
+ ```
24
+
25
+ `build` runs `tsup` (dual CJS + ESM output) and then `npm publish`. Bump the `version` in `package.json` first.
@@ -0,0 +1,163 @@
1
+ const infinite = 1e300;
2
+
3
+ const isInfinite = ( value ) => value === infinite;
4
+
5
+ const megabyte = ( 1024 * 1024 );
6
+ const gigabyte = ( megabyte * 1024 );
7
+
8
+ const urlRoot = ( string ) => ( string?.includes( 'https' ) ? 'https://' : 'http://' );
9
+
10
+ const capitalize = ( string ) => {
11
+
12
+ return string?.charAt( 0 )?.toUpperCase() + string?.slice( 1 );
13
+
14
+ };
15
+
16
+ const formatCurrency = ({
17
+ code = 'USD',
18
+ digits = 2,
19
+ display = 'standard',
20
+ locale,
21
+ value = 0
22
+ }) => {
23
+
24
+ const resolvedLocale = locale
25
+ || ( typeof navigator !== 'undefined' ? navigator?.language : null )
26
+ || 'en-US';
27
+
28
+ const options = {
29
+ currency : code,
30
+ minimumFractionDigits : digits,
31
+ maximumFractionDigits : digits,
32
+ style : 'currency'
33
+ };
34
+
35
+ if( display === 'parts' ){
36
+
37
+ options.currencyDisplay = 'narrowSymbol';
38
+
39
+ const parts = new Intl.NumberFormat( resolvedLocale, options ).formatToParts( value );
40
+
41
+ const symbol = parts.find( ( p ) => p.type === 'currency' )?.value || '';
42
+ const number = parts
43
+ .filter( ( p ) => p.type !== 'currency' && p.type !== 'literal' )
44
+ .map( ( p ) => p.value )
45
+ .join( '' );
46
+
47
+ return symbol + number + ' ' + code;
48
+
49
+ }
50
+ return new Intl.NumberFormat( resolvedLocale, options ).format( value );
51
+
52
+ };
53
+
54
+ const formatDateString = ({
55
+ date,
56
+ locale,
57
+ options = {
58
+ day : 'numeric',
59
+ month : 'long',
60
+ weekday : 'long',
61
+ year : 'numeric'
62
+ }
63
+ }) => {
64
+
65
+ return new Date( date ).toLocaleDateString(
66
+ locale,
67
+ options
68
+ );
69
+
70
+ };
71
+
72
+ const formatNumber = (
73
+ number,
74
+ digits = 0
75
+ ) => {
76
+
77
+ return Number( number ).toLocaleString( 'en', {
78
+ minimumFractionDigits : digits,
79
+ maximumFractionDigits : digits
80
+ });
81
+
82
+ };
83
+
84
+ const getPlanFeature = ( plan, key ) => {
85
+
86
+ const error = ( plan?.features?.denied || {} )?.[ key ];
87
+ const feature = ( plan?.features?.granted || {} )?.[ key ];
88
+ const granted = Boolean( feature );
89
+
90
+ return {
91
+ granted,
92
+ message : granted ? feature : error
93
+ };
94
+
95
+ };
96
+
97
+ const regex = {
98
+ url : /^(https:\/\/)/,
99
+ protocols : /^(https?:\/\/)?(www\.)?/
100
+ };
101
+
102
+ const shareUrls = ({
103
+ formUri,
104
+ organization,
105
+ page
106
+ }) => {
107
+
108
+ const preface = urlRoot( formUri );
109
+ const base = formUri;
110
+
111
+ const qr = preface + base?.replace( preface, '' ) + '/' + page?.shortId + '?qr=1';
112
+ const short = preface + base?.replace( preface, '' ) + '/' + page?.shortId;
113
+ const url = preface + organization?.subdomain + '.' + base?.replace( preface, '' ) + '/' + page?.slug;
114
+
115
+ const clients = [
116
+ base,
117
+ qr,
118
+ short,
119
+ url
120
+ ];
121
+
122
+ const urls = {
123
+ qr,
124
+ short,
125
+ url
126
+ };
127
+
128
+ if( organization?.subdomain && page?.shortId ){
129
+
130
+ clients.push( preface + base?.replace( preface, '' ) + '/' + page?.shortId );
131
+ clients.push( preface + base?.replace( preface, '' ) + '/' + page?.shortId + '?qr=1' );
132
+ clients.push( preface + organization.subdomain + '.' + base?.replace( preface, '' ) );
133
+ clients.push( preface + organization.subdomain + '.' + base?.replace( preface, '' ) + '/' + page?.shortId );
134
+
135
+ }
136
+ if( organization?.shortId && page?.slug && page?.shortId ){
137
+
138
+ clients.push( preface + organization.shortId + '.' + base?.replace( preface, '' ) );
139
+ clients.push( preface + organization.shortId + '.' + base?.replace( preface, '' ) + '/' + page?.slug );
140
+ clients.push( preface + organization.shortId + '.' + base?.replace( preface, '' ) + '/' + page?.shortId );
141
+
142
+ }
143
+ return {
144
+ clients,
145
+ urls
146
+ };
147
+
148
+ };
149
+
150
+ module.exports = {
151
+ capitalize,
152
+ formatCurrency,
153
+ formatDateString,
154
+ formatNumber,
155
+ getPlanFeature,
156
+ gigabyte,
157
+ infinite,
158
+ isInfinite,
159
+ megabyte,
160
+ regex,
161
+ shareUrls,
162
+ urlRoot
163
+ };
@@ -0,0 +1,163 @@
1
+ const infinite = 1e300;
2
+
3
+ const isInfinite = ( value ) => value === infinite;
4
+
5
+ const megabyte = ( 1024 * 1024 );
6
+ const gigabyte = ( megabyte * 1024 );
7
+
8
+ const urlRoot = ( string ) => ( string?.includes( 'https' ) ? 'https://' : 'http://' );
9
+
10
+ const capitalize = ( string ) => {
11
+
12
+ return string?.charAt( 0 )?.toUpperCase() + string?.slice( 1 );
13
+
14
+ };
15
+
16
+ const formatCurrency = ({
17
+ code = 'USD',
18
+ digits = 2,
19
+ display = 'standard',
20
+ locale,
21
+ value = 0
22
+ }) => {
23
+
24
+ const resolvedLocale = locale
25
+ || ( typeof navigator !== 'undefined' ? navigator?.language : null )
26
+ || 'en-US';
27
+
28
+ const options = {
29
+ currency : code,
30
+ minimumFractionDigits : digits,
31
+ maximumFractionDigits : digits,
32
+ style : 'currency'
33
+ };
34
+
35
+ if( display === 'parts' ){
36
+
37
+ options.currencyDisplay = 'narrowSymbol';
38
+
39
+ const parts = new Intl.NumberFormat( resolvedLocale, options ).formatToParts( value );
40
+
41
+ const symbol = parts.find( ( p ) => p.type === 'currency' )?.value || '';
42
+ const number = parts
43
+ .filter( ( p ) => p.type !== 'currency' && p.type !== 'literal' )
44
+ .map( ( p ) => p.value )
45
+ .join( '' );
46
+
47
+ return symbol + number + ' ' + code;
48
+
49
+ }
50
+ return new Intl.NumberFormat( resolvedLocale, options ).format( value );
51
+
52
+ };
53
+
54
+ const formatDateString = ({
55
+ date,
56
+ locale,
57
+ options = {
58
+ day : 'numeric',
59
+ month : 'long',
60
+ weekday : 'long',
61
+ year : 'numeric'
62
+ }
63
+ }) => {
64
+
65
+ return new Date( date ).toLocaleDateString(
66
+ locale,
67
+ options
68
+ );
69
+
70
+ };
71
+
72
+ const formatNumber = (
73
+ number,
74
+ digits = 0
75
+ ) => {
76
+
77
+ return Number( number ).toLocaleString( 'en', {
78
+ minimumFractionDigits : digits,
79
+ maximumFractionDigits : digits
80
+ });
81
+
82
+ };
83
+
84
+ const getPlanFeature = ( plan, key ) => {
85
+
86
+ const error = ( plan?.features?.denied || {} )?.[ key ];
87
+ const feature = ( plan?.features?.granted || {} )?.[ key ];
88
+ const granted = Boolean( feature );
89
+
90
+ return {
91
+ granted,
92
+ message : granted ? feature : error
93
+ };
94
+
95
+ };
96
+
97
+ const regex = {
98
+ url : /^(https:\/\/)/,
99
+ protocols : /^(https?:\/\/)?(www\.)?/
100
+ };
101
+
102
+ const shareUrls = ({
103
+ formUri,
104
+ organization,
105
+ page
106
+ }) => {
107
+
108
+ const preface = urlRoot( formUri );
109
+ const base = formUri;
110
+
111
+ const qr = preface + base?.replace( preface, '' ) + '/' + page?.shortId + '?qr=1';
112
+ const short = preface + base?.replace( preface, '' ) + '/' + page?.shortId;
113
+ const url = preface + organization?.subdomain + '.' + base?.replace( preface, '' ) + '/' + page?.slug;
114
+
115
+ const clients = [
116
+ base,
117
+ qr,
118
+ short,
119
+ url
120
+ ];
121
+
122
+ const urls = {
123
+ qr,
124
+ short,
125
+ url
126
+ };
127
+
128
+ if( organization?.subdomain && page?.shortId ){
129
+
130
+ clients.push( preface + base?.replace( preface, '' ) + '/' + page?.shortId );
131
+ clients.push( preface + base?.replace( preface, '' ) + '/' + page?.shortId + '?qr=1' );
132
+ clients.push( preface + organization.subdomain + '.' + base?.replace( preface, '' ) );
133
+ clients.push( preface + organization.subdomain + '.' + base?.replace( preface, '' ) + '/' + page?.shortId );
134
+
135
+ }
136
+ if( organization?.shortId && page?.slug && page?.shortId ){
137
+
138
+ clients.push( preface + organization.shortId + '.' + base?.replace( preface, '' ) );
139
+ clients.push( preface + organization.shortId + '.' + base?.replace( preface, '' ) + '/' + page?.slug );
140
+ clients.push( preface + organization.shortId + '.' + base?.replace( preface, '' ) + '/' + page?.shortId );
141
+
142
+ }
143
+ return {
144
+ clients,
145
+ urls
146
+ };
147
+
148
+ };
149
+
150
+ module.exports = {
151
+ capitalize,
152
+ formatCurrency,
153
+ formatDateString,
154
+ formatNumber,
155
+ getPlanFeature,
156
+ gigabyte,
157
+ infinite,
158
+ isInfinite,
159
+ megabyte,
160
+ regex,
161
+ shareUrls,
162
+ urlRoot
163
+ };
package/dist/index.js ADDED
@@ -0,0 +1,123 @@
1
+ // index.js
2
+ var infinite = 1e300;
3
+ var isInfinite = (value) => value === infinite;
4
+ var megabyte = 1024 * 1024;
5
+ var gigabyte = megabyte * 1024;
6
+ var urlRoot = (string) => (string == null ? void 0 : string.includes("https")) ? "https://" : "http://";
7
+ var capitalize = (string) => {
8
+ var _a;
9
+ return ((_a = string == null ? void 0 : string.charAt(0)) == null ? void 0 : _a.toUpperCase()) + (string == null ? void 0 : string.slice(1));
10
+ };
11
+ var formatCurrency = ({
12
+ code = "USD",
13
+ digits = 2,
14
+ display = "standard",
15
+ locale,
16
+ value = 0
17
+ }) => {
18
+ var _a;
19
+ const resolvedLocale = locale || (typeof navigator !== "undefined" ? navigator == null ? void 0 : navigator.language : null) || "en-US";
20
+ const options = {
21
+ currency: code,
22
+ minimumFractionDigits: digits,
23
+ maximumFractionDigits: digits,
24
+ style: "currency"
25
+ };
26
+ if (display === "parts") {
27
+ options.currencyDisplay = "narrowSymbol";
28
+ const parts = new Intl.NumberFormat(resolvedLocale, options).formatToParts(value);
29
+ const symbol = ((_a = parts.find((p) => p.type === "currency")) == null ? void 0 : _a.value) || "";
30
+ const number = parts.filter((p) => p.type !== "currency" && p.type !== "literal").map((p) => p.value).join("");
31
+ return symbol + number + " " + code;
32
+ }
33
+ ;
34
+ return new Intl.NumberFormat(resolvedLocale, options).format(value);
35
+ };
36
+ var formatDateString = ({
37
+ date,
38
+ locale,
39
+ options = {
40
+ day: "numeric",
41
+ month: "long",
42
+ weekday: "long",
43
+ year: "numeric"
44
+ }
45
+ }) => {
46
+ return new Date(date).toLocaleDateString(
47
+ locale,
48
+ options
49
+ );
50
+ };
51
+ var formatNumber = (number, digits = 0) => {
52
+ return Number(number).toLocaleString("en", {
53
+ minimumFractionDigits: digits,
54
+ maximumFractionDigits: digits
55
+ });
56
+ };
57
+ var getPlanFeature = (plan, key) => {
58
+ var _a, _b, _c, _d;
59
+ const error = (_b = ((_a = plan == null ? void 0 : plan.features) == null ? void 0 : _a.denied) || {}) == null ? void 0 : _b[key];
60
+ const feature = (_d = ((_c = plan == null ? void 0 : plan.features) == null ? void 0 : _c.granted) || {}) == null ? void 0 : _d[key];
61
+ const granted = Boolean(feature);
62
+ return {
63
+ granted,
64
+ message: granted ? feature : error
65
+ };
66
+ };
67
+ var regex = {
68
+ url: /^(https:\/\/)/,
69
+ protocols: /^(https?:\/\/)?(www\.)?/
70
+ };
71
+ var shareUrls = ({
72
+ formUri,
73
+ organization,
74
+ page
75
+ }) => {
76
+ const preface = urlRoot(formUri);
77
+ const base = formUri;
78
+ const qr = preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId) + "?qr=1";
79
+ const short = preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId);
80
+ const url = preface + (organization == null ? void 0 : organization.subdomain) + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.slug);
81
+ const clients = [
82
+ base,
83
+ qr,
84
+ short,
85
+ url
86
+ ];
87
+ const urls = {
88
+ qr,
89
+ short,
90
+ url
91
+ };
92
+ if ((organization == null ? void 0 : organization.subdomain) && (page == null ? void 0 : page.shortId)) {
93
+ clients.push(preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId));
94
+ clients.push(preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId) + "?qr=1");
95
+ clients.push(preface + organization.subdomain + "." + (base == null ? void 0 : base.replace(preface, "")));
96
+ clients.push(preface + organization.subdomain + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId));
97
+ }
98
+ ;
99
+ if ((organization == null ? void 0 : organization.shortId) && (page == null ? void 0 : page.slug) && (page == null ? void 0 : page.shortId)) {
100
+ clients.push(preface + organization.shortId + "." + (base == null ? void 0 : base.replace(preface, "")));
101
+ clients.push(preface + organization.shortId + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.slug));
102
+ clients.push(preface + organization.shortId + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId));
103
+ }
104
+ ;
105
+ return {
106
+ clients,
107
+ urls
108
+ };
109
+ };
110
+ module.exports = {
111
+ capitalize,
112
+ formatCurrency,
113
+ formatDateString,
114
+ formatNumber,
115
+ getPlanFeature,
116
+ gigabyte,
117
+ infinite,
118
+ isInfinite,
119
+ megabyte,
120
+ regex,
121
+ shareUrls,
122
+ urlRoot
123
+ };
package/dist/index.mjs ADDED
@@ -0,0 +1,133 @@
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
+ // index.js
7
+ var require_index = __commonJS({
8
+ "index.js"(exports, module) {
9
+ var infinite = 1e300;
10
+ var isInfinite = (value) => value === infinite;
11
+ var megabyte = 1024 * 1024;
12
+ var gigabyte = megabyte * 1024;
13
+ var urlRoot = (string) => (string == null ? void 0 : string.includes("https")) ? "https://" : "http://";
14
+ var capitalize = (string) => {
15
+ var _a;
16
+ return ((_a = string == null ? void 0 : string.charAt(0)) == null ? void 0 : _a.toUpperCase()) + (string == null ? void 0 : string.slice(1));
17
+ };
18
+ var formatCurrency = ({
19
+ code = "USD",
20
+ digits = 2,
21
+ display = "standard",
22
+ locale,
23
+ value = 0
24
+ }) => {
25
+ var _a;
26
+ const resolvedLocale = locale || (typeof navigator !== "undefined" ? navigator == null ? void 0 : navigator.language : null) || "en-US";
27
+ const options = {
28
+ currency: code,
29
+ minimumFractionDigits: digits,
30
+ maximumFractionDigits: digits,
31
+ style: "currency"
32
+ };
33
+ if (display === "parts") {
34
+ options.currencyDisplay = "narrowSymbol";
35
+ const parts = new Intl.NumberFormat(resolvedLocale, options).formatToParts(value);
36
+ const symbol = ((_a = parts.find((p) => p.type === "currency")) == null ? void 0 : _a.value) || "";
37
+ const number = parts.filter((p) => p.type !== "currency" && p.type !== "literal").map((p) => p.value).join("");
38
+ return symbol + number + " " + code;
39
+ }
40
+ ;
41
+ return new Intl.NumberFormat(resolvedLocale, options).format(value);
42
+ };
43
+ var formatDateString = ({
44
+ date,
45
+ locale,
46
+ options = {
47
+ day: "numeric",
48
+ month: "long",
49
+ weekday: "long",
50
+ year: "numeric"
51
+ }
52
+ }) => {
53
+ return new Date(date).toLocaleDateString(
54
+ locale,
55
+ options
56
+ );
57
+ };
58
+ var formatNumber = (number, digits = 0) => {
59
+ return Number(number).toLocaleString("en", {
60
+ minimumFractionDigits: digits,
61
+ maximumFractionDigits: digits
62
+ });
63
+ };
64
+ var getPlanFeature = (plan, key) => {
65
+ var _a, _b, _c, _d;
66
+ const error = (_b = ((_a = plan == null ? void 0 : plan.features) == null ? void 0 : _a.denied) || {}) == null ? void 0 : _b[key];
67
+ const feature = (_d = ((_c = plan == null ? void 0 : plan.features) == null ? void 0 : _c.granted) || {}) == null ? void 0 : _d[key];
68
+ const granted = Boolean(feature);
69
+ return {
70
+ granted,
71
+ message: granted ? feature : error
72
+ };
73
+ };
74
+ var regex = {
75
+ url: /^(https:\/\/)/,
76
+ protocols: /^(https?:\/\/)?(www\.)?/
77
+ };
78
+ var shareUrls = ({
79
+ formUri,
80
+ organization,
81
+ page
82
+ }) => {
83
+ const preface = urlRoot(formUri);
84
+ const base = formUri;
85
+ const qr = preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId) + "?qr=1";
86
+ const short = preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId);
87
+ const url = preface + (organization == null ? void 0 : organization.subdomain) + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.slug);
88
+ const clients = [
89
+ base,
90
+ qr,
91
+ short,
92
+ url
93
+ ];
94
+ const urls = {
95
+ qr,
96
+ short,
97
+ url
98
+ };
99
+ if ((organization == null ? void 0 : organization.subdomain) && (page == null ? void 0 : page.shortId)) {
100
+ clients.push(preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId));
101
+ clients.push(preface + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId) + "?qr=1");
102
+ clients.push(preface + organization.subdomain + "." + (base == null ? void 0 : base.replace(preface, "")));
103
+ clients.push(preface + organization.subdomain + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId));
104
+ }
105
+ ;
106
+ if ((organization == null ? void 0 : organization.shortId) && (page == null ? void 0 : page.slug) && (page == null ? void 0 : page.shortId)) {
107
+ clients.push(preface + organization.shortId + "." + (base == null ? void 0 : base.replace(preface, "")));
108
+ clients.push(preface + organization.shortId + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.slug));
109
+ clients.push(preface + organization.shortId + "." + (base == null ? void 0 : base.replace(preface, "")) + "/" + (page == null ? void 0 : page.shortId));
110
+ }
111
+ ;
112
+ return {
113
+ clients,
114
+ urls
115
+ };
116
+ };
117
+ module.exports = {
118
+ capitalize,
119
+ formatCurrency,
120
+ formatDateString,
121
+ formatNumber,
122
+ getPlanFeature,
123
+ gigabyte,
124
+ infinite,
125
+ isInfinite,
126
+ megabyte,
127
+ regex,
128
+ shareUrls,
129
+ urlRoot
130
+ };
131
+ }
132
+ });
133
+ export default require_index();
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "dependencies": {
3
+ "tsup": "8.5.1",
4
+ "typescript": "5.9.3"
5
+ },
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.mjs",
10
+ "require": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "license": "ISC",
17
+ "main": "dist/index.js",
18
+ "module": "dist/index.mjs",
19
+ "name": "@drawbridge/drawbridge-utils",
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "scripts": {
24
+ "build": "tsup ./index.js && npm publish"
25
+ },
26
+ "types": "dist/index.d.ts",
27
+ "version": "0.0.1"
28
+ }