Skip to content

Commit 82077d6

Browse files
authored
Created new unlocked package (#6)
* Converted repo to be an sfdx project, bumped metadata to API v56.0 * Created new unlocked package, with an initial package version v2.1.0
1 parent 366fe56 commit 82077d6

21 files changed

+6760
-259
lines changed

.eslintignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
**/lwc/**/*.css
2+
**/lwc/**/*.html
3+
**/lwc/**/*.json
4+
**/lwc/**/*.svg
5+
**/lwc/**/*.xml
6+
**/aura/**/*.auradoc
7+
**/aura/**/*.cmp
8+
**/aura/**/*.css
9+
**/aura/**/*.design
10+
**/aura/**/*.evt
11+
**/aura/**/*.json
12+
**/aura/**/*.svg
13+
**/aura/**/*.tokens
14+
**/aura/**/*.xml
15+
**/aura/**/*.app
16+
.sfdx

.forceignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2+
# More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3+
#
4+
5+
package.xml
6+
7+
# LWC configuration files
8+
**/jsconfig.json
9+
**/.eslintrc.json
10+
11+
# LWC Jest
12+
**/__tests__/**

.gitignore

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,41 @@
1-
#Folders to exclude
2-
.settings/
3-
config/
4-
debug/
5-
deploy/
1+
# This file is used for Git repositories to specify intentionally untracked files that Git should ignore.
2+
# If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore
3+
# For useful gitignore templates see: https://github.com/github/gitignore
64

7-
#Files to exclude
5+
# Salesforce cache
6+
.sf/
7+
.sfdx/
8+
.localdevserver/
9+
.vscode/
10+
deploy-options.json
11+
12+
# LWC VSCode autocomplete
13+
**/lwc/jsconfig.json
14+
15+
# Code coverage reports
16+
test-coverage/
17+
18+
# Logs
19+
logs
820
*.log
9-
*.sublime-project
10-
*.sublime-workspace
11-
*.sublime-settings
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
25+
# Dependency directories
26+
node_modules/
27+
28+
# Eslint cache
29+
.eslintcache
30+
31+
# MacOS system files
32+
.DS_Store
33+
34+
# Windows system files
35+
Thumbs.db
36+
ehthumbs.db
37+
[Dd]esktop.ini
38+
$RECYCLE.BIN/
1239

40+
# Local environment variables
41+
.env

.husky/pre-commit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
npm run precommit

.prettierignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# List files or directories below to ignore them when running prettier
2+
# More information: https://prettier.io/docs/en/ignore.html
3+
#
4+
5+
**/staticresources/**
6+
.localdevserver
7+
.sfdx
8+
.vscode
9+
10+
coverage/

.prettierrc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"trailingComma": "none",
3+
"overrides": [
4+
{
5+
"files": "**/lwc/**/*.html",
6+
"options": { "parser": "lwc" }
7+
},
8+
{
9+
"files": "*.{cmp,page,component}",
10+
"options": { "parser": "html" }
11+
}
12+
]
13+
}

.travis.yml

Lines changed: 0 additions & 7 deletions
This file was deleted.

README.md

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
# Apex UUID
2-
[![Build Status](https://travis-ci.org/jongpie/ApexUuid.svg?branch=master)](https://travis-ci.org/jongpie/ApexUuid)
32

4-
<a href="https://githubsfdeploy.herokuapp.com" target="_blank">
5-
<img alt="Deploy to Salesforce" src="https://raw.githubusercontent.com/afawcett/githubsfdeploy/master/deploy.png">
6-
</a>
3+
Provides a way to generate a [UUID (Universally Unique Identifier)](https://en.wikipedia.org/wiki/Universally_unique_identifier) in Salesforce's Apex language. This uses Verion 4 of the UUID standard - more details available [here](<https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)>)
74

8-
## Usage
9-
Provides a way to generate a [UUID (Universally Unique Identifier)](https://en.wikipedia.org/wiki/Universally_unique_identifier) in Salesforce's Apex language. This uses Verion 4 of the UUID standard - more details available [here](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random))
5+
## Unlocked Package (no namespace) - v2.1.0
6+
7+
[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t4x000000NYNEAA4)
8+
[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t4x000000NYNEAA4)
9+
10+
# Getting Started
11+
12+
## Generating & Using A UUID
1013

11-
### Generating & using a UUID
1214
To generate a UUID, simply instantiate a new instance. The string value can be retrieved with `getValue()`
13-
```
15+
16+
```java
1417
Uuid myUuid = new Uuid();
1518
String myUuidValue = myUuid.getValue();
1619
```
@@ -19,12 +22,12 @@ You can use the UUID value as a unique ID, generated by Apex. This lets you do s
1922

2023
It's best if you create a custom field on your object to store the UUID value with these properties: Text(36) (External ID) (Unique Case Insensitive).
2124

22-
In the code samples below, the field name Uuid__c is used as an example field name.
25+
In the code samples below, the field name Uuid\_\_c is used as an example field name.
2326

24-
> ##### Example: Using a code-generated external ID (such as a UUID), we can create multiple accounts and related contacts with only 1 DML statement
27+
> #### Example: Using a code-generated external ID (such as a UUID), we can create multiple accounts and related contacts with only 1 DML statement
2528
26-
```
27-
List<Sobject> recordsToCreate = new List<Sobject>();
29+
```java
30+
List<SObject> recordsToCreate = new List<SObject>();
2831
// Create 10 sample accounts
2932
for(Integer accountCount = 0; accountCount < 10; accountCount++) {
3033
// Create a new account & set a custom external ID text field called Uuid__c
@@ -54,22 +57,29 @@ System.assertEquals(1, Limits.getDmlStatements());
5457
```
5558

5659
### Using a UUID's string value
60+
5761
If you already have a UUID as a string (previously generated in Apex, generated by an external system, etc), there are 3 static methods to help work with the string value.
62+
5863
1. **Do I have a valid UUID value?**
5964

60-
This checks if the string value matches the regex for a UUID v4, including hyphens (but it is case-insensitive)
61-
```
62-
Boolean isValid = Uuid.isValid(myUuidValue);
63-
```
65+
This checks if the string value matches the regex for a UUID v4, including hyphens (but it is case-insensitive)
66+
67+
```java
68+
Boolean isValid = Uuid.isValid(myUuidValue);
69+
```
70+
6471
2. **I have a UUID value but need to format it**
6572

66-
This returns a formatted string that follows the UUID pattern 8-4-4-4-12 in lowercase. If an invalid string is provided, a UuidException is thrown.
67-
```
68-
String formattedUuidValue = Uuid.formatValue(myUnformattedUuidValue);
69-
```
73+
This returns a formatted string that follows the UUID pattern 8-4-4-4-12 in lowercase. If an invalid string is provided, a UuidException is thrown.
74+
75+
```java
76+
String formattedUuidValue = Uuid.formatValue(myUnformattedUuidValue);
77+
```
78+
7079
3. **I have a UUID value, how can I use it to construct a UUID?**
7180

72-
This will automatically format the value for you, but the intial value must be a valid (unformatted) UUID string
73-
```
74-
Uuid myUuid = Uuid.valueOf(myUuidValue);
75-
```
81+
This will automatically format the value for you, but the intial value must be a valid (unformatted) UUID string
82+
83+
```java
84+
Uuid myUuid = Uuid.valueOf(myUuidValue);
85+
```

apex-uuid/classes/Uuid.cls

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/******************************************************************************************
2+
* This file is part of the Apex UUID project, released under the MIT License. *
3+
* See LICENSE file or go to https://github.com/jongpie/ApexUuid for full license details. *
4+
******************************************************************************************/
5+
public without sharing class Uuid {
6+
private static final Integer HEX_BASE = HEX_CHARACTERS.length();
7+
private static final String HEX_CHARACTERS = '0123456789abcdef';
8+
private static final String HEX_PREFIX = '0x';
9+
private static final List<String> HEX_CHARACTER_LIST = HEX_CHARACTERS.split(
10+
''
11+
);
12+
private static final Integer UUID_V4_LENGTH = 36;
13+
private static final String UUID_V4_REGEX = '[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}';
14+
15+
public static String formatValue(String unformattedValue) {
16+
final String invalidValueError =
17+
unformattedValue + ' is not a valid UUID value';
18+
19+
// Remove any non-alphanumeric characters
20+
unformattedValue = unformattedValue.replaceAll('[^a-zA-Z0-9]', '');
21+
22+
// If the unformatted value isn't even the right length to be valid, then throw an exception
23+
// Subtract 4 because the UUID_V4_LENGTH includes 4 '-' characters in the UUID pattern
24+
if (unformattedValue.length() != (UUID_V4_LENGTH - 4))
25+
throw new UuidException(invalidValueError);
26+
27+
// UUID Pattern: 8-4-4-4-12
28+
String formattedValue =
29+
unformattedValue.substring(0, 8) +
30+
'-' +
31+
unformattedValue.substring(8, 12) +
32+
'-' +
33+
unformattedValue.substring(12, 16) +
34+
'-' +
35+
unformattedValue.substring(16, 20) +
36+
'-' +
37+
unformattedValue.substring(20);
38+
39+
formattedValue = formattedValue.toLowerCase();
40+
41+
if (!Uuid.isValid(formattedValue))
42+
throw new UuidException(invalidValueError);
43+
44+
return formattedValue;
45+
}
46+
47+
public static Boolean isValid(String uuidValue) {
48+
if (String.isBlank(uuidValue))
49+
return false;
50+
if (uuidValue.length() != UUID_V4_LENGTH)
51+
return false;
52+
53+
Pattern uuidPattern = Pattern.compile(UUID_V4_REGEX.toLowerCase());
54+
Matcher uuidMatcher = uuidPattern.matcher(uuidValue.toLowerCase());
55+
56+
return uuidMatcher.matches();
57+
}
58+
59+
public static Uuid valueOf(String uuidValue) {
60+
return new Uuid(uuidValue);
61+
}
62+
63+
private final String value;
64+
65+
public Uuid() {
66+
this.value = this.generateValue();
67+
}
68+
69+
private Uuid(String uuidValue) {
70+
this.value = Uuid.formatValue(uuidValue);
71+
}
72+
73+
public String getValue() {
74+
return this.value;
75+
}
76+
77+
private String generateValue() {
78+
String hexValue = EncodingUtil.convertToHex(Crypto.generateAesKey(128));
79+
80+
// Version Calculation: (i & 0x0f) | 0x40
81+
// Version Format: Always begins with 4
82+
String versionShiftedHexBits = this.getShiftedHexBits(
83+
hexValue.substring(14, 16),
84+
this.convertHexToInteger('0x0f'),
85+
this.convertHexToInteger('0x40')
86+
);
87+
88+
// Variant Calculation: (i & 0x3f) | 0x80
89+
// Variant Format: Always begins with 8, 9, A or B
90+
String variantShiftedHexBits = this.getShiftedHexBits(
91+
hexValue.substring(18, 20),
92+
this.convertHexToInteger('0x3f'),
93+
this.convertHexToInteger('0x80')
94+
);
95+
96+
String uuidValue =
97+
hexValue.substring(0, 8) + // time-low
98+
hexValue.substring(8, 12) + // time-mid
99+
versionShiftedHexBits +
100+
hexValue.substring(14, 16) + // time-high-and-version
101+
variantShiftedHexBits +
102+
hexValue.substring(18, 20) + // clock-seq-and-reserved + clock-seq-low
103+
hexValue.substring(20); // node
104+
105+
return Uuid.formatValue(uuidValue);
106+
}
107+
108+
private String getShiftedHexBits(
109+
String hexSubstring,
110+
Integer lowerThreshold,
111+
Integer upperThreshold
112+
) {
113+
Integer shiftedIntegerBits =
114+
(this.convertHexToInteger(hexSubstring) & lowerThreshold) |
115+
upperThreshold;
116+
return this.convertIntegerToHex(shiftedIntegerBits);
117+
}
118+
119+
private Integer convertHexToInteger(String hexValue) {
120+
hexValue = hexValue.toLowerCase();
121+
122+
if (hexValue.startsWith(HEX_PREFIX))
123+
hexValue = hexValue.substringAfter(HEX_PREFIX);
124+
125+
Integer integerValue = 0;
126+
for (String hexCharacter : hexValue.split('')) {
127+
Integer hexCharacterIndex = HEX_CHARACTERS.indexOf(hexCharacter);
128+
129+
integerValue = HEX_BASE * integerValue + hexCharacterIndex;
130+
}
131+
return integerValue;
132+
}
133+
134+
private String convertIntegerToHex(Integer integerValue) {
135+
String hexValue = '';
136+
while (integerValue > 0) {
137+
Integer hexCharacterIndex = Math.mod(integerValue, HEX_BASE);
138+
139+
hexValue = HEX_CHARACTER_LIST[hexCharacterIndex] + hexValue;
140+
integerValue = integerValue / HEX_BASE;
141+
}
142+
return hexValue;
143+
}
144+
145+
private class UuidException extends Exception {
146+
}
147+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
<?xml version="1.0" encoding="UTF-8"?>
1+
<?xml version="1.0" encoding="UTF-8" ?>
22
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3-
<apiVersion>46.0</apiVersion>
3+
<apiVersion>56.0</apiVersion>
44
<status>Active</status>
55
</ApexClass>

0 commit comments

Comments
 (0)