mirror of
https://github.com/sasjs/adapter.git
synced 2025-12-11 01:14:36 +00:00
Compare commits
383 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a6845ad6a | ||
|
|
61d66c6f82 | ||
| 123fbc7235 | |||
|
|
0b755b7304 | ||
|
|
0816b7b1f9 | ||
|
|
a34eebba44 | ||
| 857e39eb33 | |||
| 9bd7d84975 | |||
| 731e38bce3 | |||
|
|
b80283f8af | ||
|
|
291e23e40a | ||
| d53d1e1e6a | |||
| 8cf249e8fd | |||
| 5d7cfe1e6c | |||
| abc15fb3ab | |||
| 8cc4270e48 | |||
|
|
9493492dea | ||
|
|
9b976d48ca | ||
|
|
00b19de497 | ||
|
|
f4cdd2d607 | ||
|
|
cdc0c12ec4 | ||
|
|
bc6f109c48 | ||
|
|
cfab64cfa0 | ||
|
|
d4c8c58552 | ||
|
|
2b8cb51a50 | ||
|
|
e068d3263c | ||
| 630f2e9c37 | |||
| 51ac6b052b | |||
| c32258eb3c | |||
|
|
88f50e3c74 | ||
|
|
bfe5ac0ff7 | ||
|
|
d50f5a030a | ||
|
|
c320caec99 | ||
|
|
16a5b2b012 | ||
|
|
2951e0cc2d | ||
|
|
6bb4a7ea18 | ||
|
|
2827978fe5 | ||
|
|
541c19c1a4 | ||
|
|
c5e995f8d6 | ||
|
|
8bf36da566 | ||
| ccb4ec6e03 | |||
| 06ebb52bc9 | |||
|
|
6e23a0362f | ||
| a59d78bcf7 | |||
| 33d4ee92a7 | |||
| dadce3d4c9 | |||
|
|
b61cf34723 | ||
|
|
22445d1268 | ||
|
|
cba9dacb37 | ||
|
|
a055b36c5c | ||
| 06895cc9f8 | |||
| 24496a997a | |||
| 6419686269 | |||
|
|
4554c9100c | ||
| 919c83c143 | |||
| 00ba2957fb | |||
| 5beda6547a | |||
| bd49b3757a | |||
|
|
b32352a369 | ||
| b306f11148 | |||
|
|
8c4955cb65 | ||
|
|
155f2bb0e8 | ||
| 3ca971134a | |||
| 488d8b9316 | |||
| c20bdba4ae | |||
| 0be2d69aee | |||
| a6e67c3478 | |||
| 5968988984 | |||
| 31cd01610a | |||
| a67824762c | |||
|
|
0336541d40 | ||
|
|
01de3836d7 | ||
|
|
c571bb8490 | ||
|
|
5b4d354ea2 | ||
|
|
b0ce0dc40a | ||
| 88f70a7966 | |||
| 89ff323206 | |||
| d4357d939e | |||
|
|
6cb76f0b5c | ||
|
|
ba2baa36c0 | ||
|
|
e36cd785e8 | ||
| 2fa3a353fa | |||
|
|
bdb1ffb2ef | ||
|
|
84090661cf | ||
|
|
68e14bbf05 | ||
|
|
e4f23334d3 | ||
|
|
5593963b89 | ||
|
|
81c9138b93 | ||
|
|
83fa82108b | ||
|
|
76039c3ec7 | ||
|
|
9b57c9ca1c | ||
|
|
4018cf95ba | ||
|
|
173b6e3e8d | ||
|
|
0ed5447aff | ||
|
|
6344a906d8 | ||
|
|
b2c135ae61 | ||
|
|
2032aacba3 | ||
|
|
fadccfc94c | ||
|
|
551e4e43c1 | ||
|
|
1867658cde | ||
| 3fff4f9c4d | |||
|
|
3f119432db | ||
| 0b18fddc3e | |||
| 19503e0b31 | |||
| d8bdc02f09 | |||
| 2d0833061f | |||
|
|
5dfc4e4086 | ||
|
|
c5824a8a8d | ||
|
|
2147c59314 | ||
|
|
56a1960fff | ||
| b8c9522a55 | |||
| b461cff731 | |||
| 728167fd71 | |||
| 460575b462 | |||
|
|
b247da249a | ||
|
|
e79089b880 | ||
|
|
fe907e1c43 | ||
|
|
e95e894365 | ||
|
|
82414d8b8b | ||
|
|
456fa68f0f | ||
|
|
076adc1f6a | ||
|
|
9676488ff2 | ||
|
|
e9affb862d | ||
|
|
e04371510e | ||
|
|
19657a1c12 | ||
|
|
6424c82ac9 | ||
|
|
fcab18191f | ||
|
|
f157612a0e | ||
|
|
b8cb7d52e7 | ||
|
|
d8d1968162 | ||
|
|
0e1d1f1d99 | ||
|
|
0b055dd05f | ||
|
|
ba91c29ba8 | ||
|
|
bd19457c2a | ||
|
|
b0570e1cd9 | ||
|
|
a5f1b59f7b | ||
|
|
01ca29fc01 | ||
|
|
ed9648fdf9 | ||
|
|
7e17aa6eb3 | ||
|
|
9caee9941a | ||
|
|
e309e7a4f4 | ||
|
|
c47441d6d4 | ||
|
|
1844bc48ac | ||
|
|
7a5adebdb5 | ||
|
|
b39f0c577b | ||
|
|
15f4065cd8 | ||
|
|
4c67665b4d | ||
|
|
55e64ae9d6 | ||
|
|
76d0b82b4c | ||
|
|
95d65d270d | ||
|
|
4e5c9c1ccd | ||
|
|
3267af0724 | ||
|
|
75120424d0 | ||
|
|
f13c7e5cf1 | ||
|
|
53a7b1c9e6 | ||
|
|
8c30cbff13 | ||
|
|
8f3a7f33f8 | ||
|
|
67ec27bab7 | ||
|
|
c1b200b0d8 | ||
|
|
e03ec996d6 | ||
|
|
ad8dbfd4ec | ||
|
|
15a774ff81 | ||
|
|
98114c5591 | ||
|
|
f8c6318a88 | ||
|
|
dffcb66d54 | ||
|
|
67c7147e62 | ||
|
|
50d1b4d824 | ||
|
|
dc98ce3b0b | ||
|
|
cf1e3f3835 | ||
|
|
2f913e9363 | ||
|
|
05a9864df8 | ||
|
|
3a0d764dfa | ||
|
|
310087b895 | ||
|
|
dc39ecd4a8 | ||
|
|
99e192c5de | ||
|
|
b86658ef9b | ||
|
|
88f08e8864 | ||
|
|
80e5de5d65 | ||
|
|
665734b168 | ||
|
|
5543f467e6 | ||
|
|
a32c0879b3 | ||
|
|
bb2ad5bb9a | ||
|
|
6f2f11d112 | ||
|
|
9b32b28aa7 | ||
|
|
fef65bbfd2 | ||
|
|
efeba71612 | ||
|
|
8f54002b1e | ||
|
|
9d6882799d | ||
|
|
73a3acee68 | ||
|
|
0a88220e04 | ||
|
|
c8e1779272 | ||
|
|
8bd3580e23 | ||
|
|
f732b32873 | ||
|
|
65b18f9148 | ||
|
|
10b1676a35 | ||
|
|
b9bd09d3e8 | ||
|
|
537f687b94 | ||
|
|
bfd532f813 | ||
|
|
4f2b4f46a8 | ||
|
|
077cc9458d | ||
|
|
0a7ab394a4 | ||
|
|
f873febfde | ||
|
|
55e8ce359b | ||
|
|
99d7c8f119 | ||
|
|
b3c90f09d6 | ||
|
|
2401962c53 | ||
|
|
362b4d4db3 | ||
|
|
8aea325139 | ||
|
|
bb370061a2 | ||
|
|
48442f7769 | ||
|
|
e67a8531ce | ||
|
|
ef4f020e2a | ||
|
|
2feceeb2f9 | ||
|
|
eaec922fea | ||
|
|
de94777fff | ||
|
|
0aa0ae65e0 | ||
|
|
4b0d62d59b | ||
|
|
b3ef50e9eb | ||
|
|
d30a1890a1 | ||
|
|
f1c2569de3 | ||
|
|
4826388cdd | ||
| e88736056a | |||
| 9da2a29a72 | |||
| dce8a08a86 | |||
| 1fabb9e610 | |||
| 23db0ac80d | |||
| 28370341d8 | |||
|
|
a023ffe850 | ||
|
|
a4e77ecf6e | ||
|
|
7efc0a1fb2 | ||
|
|
c3e2b2ce70 | ||
|
|
dde1228b1d | ||
|
|
b3474b6dfb | ||
|
|
179a04ae31 | ||
|
|
2bdcbda54c | ||
|
|
a123392c56 | ||
|
|
719135e366 | ||
|
|
ba619554b7 | ||
|
|
6a3ab7032f | ||
|
|
d818d14cb4 | ||
|
|
599c130395 | ||
|
|
9ef2759e27 | ||
|
|
43355c88d4 | ||
|
|
15e1acaf4f | ||
|
|
ec77ffdd88 | ||
|
|
9797c1ca84 | ||
|
|
bbe9633dc8 | ||
|
|
6f60ac5cc7 | ||
|
|
e7ba09793c | ||
|
|
c0c0800e61 | ||
|
|
0bd9d8f93f | ||
|
|
214fc2d5cd | ||
|
|
55b0e2f934 | ||
|
|
609cd4ed6d | ||
|
|
2b20bbdcc8 | ||
|
|
946a95bea1 | ||
|
|
7ec1c152e3 | ||
|
|
0cf1110018 | ||
|
|
9c5ada6fa1 | ||
|
|
0f5702e21b | ||
|
|
f10d6ec80a | ||
|
|
490215df90 | ||
|
|
9d27451813 | ||
|
|
a977f59675 | ||
|
|
51a09d049c | ||
|
|
47be5e77e5 | ||
|
|
d517e79ec0 | ||
|
|
8714ecdde8 | ||
|
|
2cffc57209 | ||
|
|
4e43687de2 | ||
|
|
f8dab83e37 | ||
|
|
655af03cf3 | ||
|
|
0a4dd00edb | ||
|
|
55b4929c54 | ||
|
|
8eb73a6b3c | ||
|
|
0aeb201625 | ||
|
|
e0140a23c2 | ||
|
|
ff6698a9d1 | ||
|
|
843d498b72 | ||
|
|
349612a065 | ||
|
|
e48b22128d | ||
|
|
14dfe4ec51 | ||
|
|
f679b17cbe | ||
|
|
36a0f0e743 | ||
|
|
ad563b9bc8 | ||
|
|
e0051bf276 | ||
|
|
7b72998e1c | ||
|
|
893cce7f21 | ||
|
|
bf7e8fd0e6 | ||
|
|
66d02cf1d1 | ||
|
|
f2c8e40430 | ||
|
|
4b28ee8e73 | ||
|
|
c7e54cfe9f | ||
|
|
50be3acc78 | ||
|
|
66c12a69bb | ||
|
|
e2058f0c71 | ||
|
|
75a74152a5 | ||
|
|
9344c4fd35 | ||
|
|
be0fe00076 | ||
|
|
a2069ee48b | ||
|
|
907885cf85 | ||
|
|
f10ed3236e | ||
|
|
a852a0af7c | ||
|
|
03f3550774 | ||
|
|
2e8d06f9e1 | ||
|
|
1d31ec4dcc | ||
|
|
4407ed68ae | ||
|
|
b3359f2138 | ||
|
|
cff9104adf | ||
|
|
b73f821c19 | ||
|
|
dd3c1a7375 | ||
|
|
c10b5368af | ||
|
|
2df66765c0 | ||
|
|
ed65545571 | ||
|
|
b4ae486520 | ||
|
|
bb7b3d0b84 | ||
|
|
65b34aa015 | ||
|
|
b3c9303def | ||
|
|
19dfda9b6a | ||
|
|
ce2abb448f | ||
|
|
413c3b8098 | ||
|
|
269514a44f | ||
|
|
5fc334dd8b | ||
|
|
1b251f1cea | ||
|
|
70d3e25c7f | ||
|
|
5e9b33e346 | ||
|
|
eb52ec7532 | ||
|
|
f46c4bf3ca | ||
|
|
d8176912cf | ||
|
|
4c54ade2d3 | ||
|
|
52c41dfb3a | ||
|
|
36f0aa7411 | ||
|
|
a10e4ec264 | ||
|
|
851b6bc273 | ||
|
|
23f8d31b1b | ||
|
|
a5683bcd07 | ||
|
|
c7be71c781 | ||
|
|
594f274323 | ||
|
|
ba1ed5e732 | ||
|
|
613cc6b9ef | ||
|
|
8edb00f869 | ||
|
|
60a1f84604 | ||
|
|
36cfaee5db | ||
|
|
cb607c93ca | ||
|
|
03b5e1d824 | ||
|
|
2ea49a425f | ||
|
|
3c894c4147 | ||
|
|
23d151c919 | ||
|
|
6d1c4ff81a | ||
|
|
7a6e6e8333 | ||
|
|
0eba6bdcf4 | ||
|
|
d7ecaf5932 | ||
|
|
e0d85f458b | ||
|
|
3a9cd46e6e | ||
|
|
301edab8ad | ||
|
|
aed39c2ec4 | ||
|
|
cc594eca52 | ||
|
|
3fbca2835e | ||
|
|
61ed5c4fa7 | ||
|
|
e31774ae9d | ||
|
|
00f09179a8 | ||
|
|
4196901e01 | ||
|
|
bf35dd072a | ||
|
|
75e3fd018d | ||
|
|
965dfff7c6 | ||
|
|
ff64dd22ad | ||
|
|
e7cceab065 | ||
|
|
f789b8f7a2 | ||
|
|
9b6ba3548f | ||
|
|
efa4c71b8a | ||
|
|
ecfc1a4bf8 | ||
|
|
246b855c76 | ||
|
|
80aa848617 | ||
|
|
acf045965e | ||
|
|
5a7f64dc35 | ||
|
|
de447b0727 | ||
|
|
a2906abf71 | ||
|
|
ace16efd93 | ||
|
|
13ae5ae756 | ||
|
|
f1b035032f | ||
|
|
1555afe771 | ||
|
|
a2832f1e1a | ||
|
|
56f34508fa |
18
.git-hooks/commit-msg
Executable file
18
.git-hooks/commit-msg
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
RED="\033[1;31m"
|
||||
GREEN="\033[1;32m"
|
||||
|
||||
# Get the commit message (the parameter we're given is just the path to the
|
||||
# temporary file which holds the message).
|
||||
commit_message=$(cat "$1")
|
||||
|
||||
if (echo "$commit_message" | grep -Eq "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-z0-9 \-]+\))?!?: .+$") then
|
||||
echo "${GREEN} ✔ Commit message meets Conventional Commit standards"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "${RED}❌ Commit message does not meet the Conventional Commit standard!"
|
||||
echo "An example of a valid message is:"
|
||||
echo " feat(login): add the 'remember me' button"
|
||||
echo "ℹ More details at: https://www.conventionalcommits.org/en/v1.0.0/#summary"
|
||||
exit 1
|
||||
7
.github/dependabot.yml
vendored
Normal file
7
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
5
.github/reviewer-lottery.yml
vendored
5
.github/reviewer-lottery.yml
vendored
@@ -7,3 +7,8 @@ groups:
|
||||
- saadjutt01
|
||||
- medjedovicm
|
||||
- allanbowe
|
||||
- sabhas
|
||||
- name: SASjs QA
|
||||
reviewers: 1
|
||||
usernames:
|
||||
- VladislavParhomchik
|
||||
|
||||
2
.github/workflows/npmpublish.yml
vendored
2
.github/workflows/npmpublish.yml
vendored
@@ -25,3 +25,5 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
- name: Send Slack message
|
||||
run: curl -X POST --data-urlencode "payload={\"channel\":\"#sasjs\", \"username\":\"GitHub CI\", \"text\":\"New version of @sasjs/adapter has been released! \n Please deploy and run `dctests` with new adapter to make sure everything is still in place.\", \"icon_emoji\":\":rocket:\"}" ${{ secrets.SLACK_WEBHOOK }}
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,4 +3,6 @@ build
|
||||
|
||||
.env
|
||||
|
||||
/coverage
|
||||
/coverage
|
||||
|
||||
.DS_Store
|
||||
4
.npmignore
Normal file
4
.npmignore
Normal file
@@ -0,0 +1,4 @@
|
||||
sasjs-tests/
|
||||
docs/
|
||||
.github/
|
||||
CONTRIBUTING.md
|
||||
@@ -1,5 +1,9 @@
|
||||
# Change Log
|
||||
|
||||
Since March 2020 the changelog is managed by github releases - see [https://github.com/sasjs/adapter/releases](https://github.com/sasjs/adapter/releases).
|
||||
|
||||
## Changes up to 5th March 2020
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
<a name="1.9.0"></a>
|
||||
|
||||
@@ -2,75 +2,127 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at support@macropeople.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
reported to the community leaders responsible for enforcement at
|
||||
https://sasapps.io/contact-us.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Macro People
|
||||
Copyright (c) 2021 Macro People
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -12,6 +12,8 @@ What code changes have been made to achieve the intent.
|
||||
|
||||
## Checks
|
||||
|
||||
No PR (that involves a non-trivial code change) should be merged, unless all four of the items below are confirmed! If an urgent fix is needed - use a tar file.
|
||||
|
||||
- [ ] Code is formatted correctly (`npm run lint:fix`).
|
||||
- [ ] All unit tests are passing (`npm test`).
|
||||
- [ ] All `sasjs-cli` unit tests are passing (`npm test`).
|
||||
|
||||
188
README.md
188
README.md
@@ -1,12 +1,28 @@
|
||||
[](https://www.jsdelivr.com/package/npm/@sasjs/adapter)
|
||||
|
||||
# @sasjs/adapter
|
||||
|
||||
[![npm package][npm-image]][npm-url]
|
||||
[![Github Workflow][githubworkflow-image]][githubworkflow-url]
|
||||
[![Dependency Status][dependency-image]][dependency-url]
|
||||
[]()
|
||||

|
||||
[](/LICENSE)
|
||||

|
||||

|
||||
[](https://gitpod.io/#https://github.com/sasjs/adapter)
|
||||
|
||||
|
||||
[npm-image]:https://img.shields.io/npm/v/@sasjs/adapter.svg
|
||||
[npm-url]:http://npmjs.org/package/@sasjs/adapter
|
||||
[githubworkflow-image]:https://github.com/sasjs/adapter/actions/workflows/build.yml/badge.svg
|
||||
[githubworkflow-url]:https://github.com/sasjs/adapter/blob/main/.github/workflows/build.yml
|
||||
[dependency-image]:https://david-dm.org/sasjs/adapter.svg
|
||||
[dependency-url]:https://github.com/sasjs/adapter/blob/main/package.json
|
||||
|
||||
SASjs is a open-source framework for building Web Apps on SAS® platforms. You can use as much or as little of it as you like. This repository contains the JS adapter, the part that handles the to/from SAS communication on the client side. There are 3 ways to install it:
|
||||
|
||||
1 - `npm install @sasjs/adapter` - for use in a node project
|
||||
|
||||
2 - [Download](https://cdn.jsdelivr.net/npm/@sasjs/adapter@1/index.js) and use a copy of the latest JS file
|
||||
2 - [Download](https://cdn.jsdelivr.net/npm/@sasjs/adapter@2/index.js) and use a copy of the latest JS file
|
||||
|
||||
3 - Reference directly from the CDN - in which case click [here](https://www.jsdelivr.com/package/npm/@sasjs/adapter?tab=collection) and select "SRI" to get the script tag with the integrity hash.
|
||||
|
||||
@@ -41,8 +57,174 @@ parmcards4;
|
||||
|
||||
You now have a simple web app with a backend service!
|
||||
|
||||
## Detailed Overview
|
||||
|
||||
The SASjs adapter is a JS library and a set of SAS Macros that handle the communication between the frontend app and backend SAS services.
|
||||
|
||||
There are three parts to consider:
|
||||
|
||||
1. JS request / response
|
||||
2. SAS inputs / outputs
|
||||
3. Configuration
|
||||
|
||||
### JS Request / Response
|
||||
|
||||
To install the library you can simply run `npm i @sasjs/adapter` or include a `<script>` tag with a reference to our [CDN](https://www.jsdelivr.com/package/npm/@sasjs/adapter).
|
||||
|
||||
Full technical documentation is available [here](https://adapter.sasjs.io). The main parts are:
|
||||
|
||||
### Instantiation
|
||||
The following code will instantiate an instance of the adapter:
|
||||
|
||||
```javascript
|
||||
let sasJs = new SASjs.default(
|
||||
{
|
||||
appLoc: "/Your/SAS/Folder",
|
||||
serverType:"SAS9"
|
||||
}
|
||||
);
|
||||
```
|
||||
If you've installed it via NPM, you can import it as a default import like so:
|
||||
```
|
||||
import SASjs from '@sasjs/adapter';
|
||||
```
|
||||
You can then instantiate it with:
|
||||
```
|
||||
const sasJs = new SASjs({your config})
|
||||
```
|
||||
|
||||
More on the config later.
|
||||
|
||||
### SAS Logon
|
||||
The login process can be handled directly, as below, or as a callback function to a SAS request.
|
||||
|
||||
```javascript
|
||||
sasJs.logIn('USERNAME','PASSWORD'
|
||||
).then((response) => {
|
||||
if (response.isLoggedIn === true) {
|
||||
console.log('do stuff')
|
||||
} else {
|
||||
console.log('do other stuff')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Request / Response
|
||||
A simple request can be sent to SAS in the following fashion:
|
||||
|
||||
```javascript
|
||||
sasJs.request("/path/to/my/service", dataObject)
|
||||
.then((response) => {
|
||||
// all tables are in the response object, eg:
|
||||
console.log(response.tablewith2cols1row[0].COL1.value)
|
||||
})
|
||||
```
|
||||
We supply the path to the SAS service, and a data object. The data object can be null (for services with no input), or can contain one or more tables in the following format:
|
||||
|
||||
```javascript
|
||||
let dataObject={
|
||||
"tablewith2cols1row": [{
|
||||
"col1": "val1",
|
||||
"col2": 42
|
||||
}],
|
||||
"tablewith1col2rows": [{
|
||||
"col": "row1"
|
||||
}, {
|
||||
"col": "row2"
|
||||
}]
|
||||
};
|
||||
```
|
||||
|
||||
There are optional parameters such as a config object and a callback login function.
|
||||
|
||||
The response object will contain returned tables and columns. Table names are always lowercase, and column names uppercase.
|
||||
|
||||
The adapter will also cache the logs (if debug enabled) and even the work tables. For performance, it is best to keep debug mode off.
|
||||
|
||||
## SAS Inputs / Outputs
|
||||
|
||||
The SAS side is handled by a number of macros in the [macro core](https://github.com/sasjs/core) library.
|
||||
|
||||
The following snippet shows the process of SAS tables arriving / leaving:
|
||||
```sas
|
||||
/* fetch all input tables sent from frontend - they arrive as work tables */
|
||||
%webout(FETCH)
|
||||
|
||||
/* some sas code */
|
||||
data some sas tables;
|
||||
set from js;
|
||||
run;
|
||||
|
||||
%webout(OPEN) /* open the JSON to be returned */
|
||||
%webout(OBJ,some) /* `some` table is sent in object format */
|
||||
%webout(ARR,sas) /* `sas` table is sent in array format, smaller filesize */
|
||||
%webout(OBJ,tables,fmt=N) /* unformatted (raw) data */
|
||||
%webout(OBJ,tables,label=newtable) /* rename tables on export */
|
||||
%webout(CLOSE) /* close the JSON and send some extra useful variables too */
|
||||
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuration on the client side involves passing an object on startup, which can also be passed with each request. Technical documentation on the SASjsConfig class is available [here](https://adapter.sasjs.io/classes/types.sasjsconfig.html). The main config items are:
|
||||
|
||||
* `appLoc` - this is the folder under which the SAS services will be created.
|
||||
* `serverType` - either `SAS9` or `SASVIYA`.
|
||||
* `serverUrl` - the location (including http protocol and port) of the SAS Server. Can be omitted, eg if serving directly from the SAS Web Server, or in streaming mode.
|
||||
* `debug` - if `true` then SAS Logs and extra debug information is returned.
|
||||
* `useComputeApi` - Only relevant when the serverType is `SASVIYA`. If `true` the [Compute API](#using-the-compute-api) is used. If `false` the [JES API](#using-the-jes-api) is used. If `null` or `undefined` the [Web](#using-jes-web-app) approach is used.
|
||||
* `contextName` - Compute context on which the requests will be called. If missing or not provided, defaults to `Job Execution Compute context`.
|
||||
|
||||
The adapter supports a number of approaches for interfacing with Viya (`serverType` is `SASVIYA`). For maximum performance, be sure to [configure your compute context](https://sasjs.io/guide-viya/#shared-account-and-server-re-use) with `reuseServerProcesses` as `true` and a system account in `runServerAs`. This functionality is available since Viya 3.5. This configuration is supported when [creating contexts using the CLI](https://sasjs.io/sasjs-cli-context/#sasjs-context-create).
|
||||
|
||||
### Using JES Web App
|
||||
|
||||
In this setup, all requests are routed through the JES web app, at `YOURSERVER/SASJobExecution?_program=/your/program`. This is the most reliable method, and also the slowest. One request is made to the JES app, and remaining requests (getting job uri, session spawning, passing parameters, running the program, fetching the log) are handled by the SAS server inside the JES app.
|
||||
|
||||
```
|
||||
{
|
||||
appLoc:"/Your/Path",
|
||||
serverType:"SASVIYA",
|
||||
contextName: 'yourComputeContext'
|
||||
}
|
||||
```
|
||||
|
||||
### Using the JES API
|
||||
Here we are running Jobs using the Job Execution Service except this time we are making the requests directly using the REST API instead of through the JES Web App. This is helpful when we need to call web services outside of a browser (eg with the SASjs CLI or other commandline tools). To save one network request, the adapter prefetches the JOB URIs and passes them in the `__job` parameter. Depending on your network bandwidth, it may or may not be faster than the JES Web approach.
|
||||
|
||||
```
|
||||
{
|
||||
appLoc:"/Your/Path",
|
||||
serverType:"SASVIYA",
|
||||
useComputeApi: false,
|
||||
contextName: 'yourComputeContext'
|
||||
}
|
||||
```
|
||||
|
||||
### Using the Compute API
|
||||
This approach is by far the fastest, as a result of the optimisations we have built into the adapter. With this configuration, in the first sasjs request, we take a URI map of the services in the target folder, and create a session manager. This manager will spawn a additional session every time a request is made. Subsequent requests will use the existing 'hot' session, if it exists. Sessions are always deleted after every use, which actually makes this _less_ resource intensive than a typical JES web app, in which all sessions are kept alive by default for 15 minutes.
|
||||
|
||||
```
|
||||
{
|
||||
appLoc:"/Your/Path",
|
||||
serverType:"SASVIYA",
|
||||
useComputeApi: true,
|
||||
contextName: 'yourComputeContext'
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# More resources
|
||||
|
||||
For more information and examples specific to this adapter you can check out the [user guide](https://sasjs.io/sasjs-adapter/) or the [technical](http://adapter.sasjs.io/) documentation.
|
||||
|
||||
For more information on building web apps in general, check out these [resources](https://sasjs.io/training/resources/) or contact the [author](https://www.linkedin.com/in/allanbowe/) directly.
|
||||
|
||||
If you are a SAS 9 or SAS Viya customer you can also request a copy of [Data Controller](https://datacontroller.io) - free for up to 5 users, this tool makes use of all parts of the SASjs framework.
|
||||
|
||||
|
||||
## Star Gazing
|
||||
|
||||
If you find this library useful, help us grow our star graph!
|
||||
|
||||

|
||||
|
||||
13
cypress.json
13
cypress.json
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"defaultCommandTimeout": 10000,
|
||||
"chromeWebSecurity": false,
|
||||
"screenshotOnRunFailure": false,
|
||||
"env": {
|
||||
"serverUrl": "",
|
||||
"appLoc": "/Public/app",
|
||||
"serverType": "SAS9",
|
||||
"debug": false,
|
||||
"username": "",
|
||||
"password": ""
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
328
docs/classes/auth.authmanager.html
Normal file
328
docs/classes/auth.authmanager.html
Normal file
File diff suppressed because one or more lines are too long
435
docs/classes/job_execution.basejobexecutor.html
Normal file
435
docs/classes/job_execution.basejobexecutor.html
Normal file
File diff suppressed because one or more lines are too long
438
docs/classes/job_execution.computejobexecutor.html
Normal file
438
docs/classes/job_execution.computejobexecutor.html
Normal file
File diff suppressed because one or more lines are too long
438
docs/classes/job_execution.jesjobexecutor.html
Normal file
438
docs/classes/job_execution.jesjobexecutor.html
Normal file
File diff suppressed because one or more lines are too long
444
docs/classes/job_execution.webjobexecutor.html
Normal file
444
docs/classes/job_execution.webjobexecutor.html
Normal file
File diff suppressed because one or more lines are too long
231
docs/classes/reflection-817.reflection-220.fileuploader.html
Normal file
231
docs/classes/reflection-817.reflection-220.fileuploader.html
Normal file
File diff suppressed because one or more lines are too long
312
docs/classes/reflection-817.reflection-220.sas9apiclient.html
Normal file
312
docs/classes/reflection-817.reflection-220.sas9apiclient.html
Normal file
File diff suppressed because one or more lines are too long
1715
docs/classes/reflection-817.reflection-220.sasjs.html
Normal file
1715
docs/classes/reflection-817.reflection-220.sasjs.html
Normal file
File diff suppressed because one or more lines are too long
1516
docs/classes/reflection-817.reflection-220.sasviyaapiclient.html
Normal file
1516
docs/classes/reflection-817.reflection-220.sasviyaapiclient.html
Normal file
File diff suppressed because one or more lines are too long
323
docs/classes/reflection-817.reflection-220.sessionmanager.html
Normal file
323
docs/classes/reflection-817.reflection-220.sessionmanager.html
Normal file
File diff suppressed because one or more lines are too long
231
docs/classes/reflection-830.reflection-222.fileuploader.html
Normal file
231
docs/classes/reflection-830.reflection-222.fileuploader.html
Normal file
File diff suppressed because one or more lines are too long
312
docs/classes/reflection-830.reflection-222.sas9apiclient.html
Normal file
312
docs/classes/reflection-830.reflection-222.sas9apiclient.html
Normal file
File diff suppressed because one or more lines are too long
1721
docs/classes/reflection-830.reflection-222.sasjs.html
Normal file
1721
docs/classes/reflection-830.reflection-222.sasjs.html
Normal file
File diff suppressed because one or more lines are too long
1528
docs/classes/reflection-830.reflection-222.sasviyaapiclient.html
Normal file
1528
docs/classes/reflection-830.reflection-222.sasviyaapiclient.html
Normal file
File diff suppressed because one or more lines are too long
360
docs/classes/reflection-830.reflection-222.sessionmanager.html
Normal file
360
docs/classes/reflection-830.reflection-222.sessionmanager.html
Normal file
File diff suppressed because one or more lines are too long
551
docs/classes/request.requestclient.html
Normal file
551
docs/classes/request.requestclient.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
328
docs/classes/types.authorizeerror.html
Normal file
328
docs/classes/types.authorizeerror.html
Normal file
File diff suppressed because one or more lines are too long
346
docs/classes/types.computejobexecutionerror.html
Normal file
346
docs/classes/types.computejobexecutionerror.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
367
docs/classes/types.jobexecutionerror.html
Normal file
367
docs/classes/types.jobexecutionerror.html
Normal file
File diff suppressed because one or more lines are too long
301
docs/classes/types.loginrequirederror.html
Normal file
301
docs/classes/types.loginrequirederror.html
Normal file
File diff suppressed because one or more lines are too long
325
docs/classes/types.notfounderror.html
Normal file
325
docs/classes/types.notfounderror.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
286
docs/classes/types_errors.authorizeerror.html
Normal file
286
docs/classes/types_errors.authorizeerror.html
Normal file
File diff suppressed because one or more lines are too long
304
docs/classes/types_errors.computejobexecutionerror.html
Normal file
304
docs/classes/types_errors.computejobexecutionerror.html
Normal file
File diff suppressed because one or more lines are too long
209
docs/classes/types_errors.errorresponse.html
Normal file
209
docs/classes/types_errors.errorresponse.html
Normal file
File diff suppressed because one or more lines are too long
259
docs/classes/types_errors.internalservererror.html
Normal file
259
docs/classes/types_errors.internalservererror.html
Normal file
File diff suppressed because one or more lines are too long
325
docs/classes/types_errors.jobexecutionerror.html
Normal file
325
docs/classes/types_errors.jobexecutionerror.html
Normal file
File diff suppressed because one or more lines are too long
259
docs/classes/types_errors.loginrequirederror.html
Normal file
259
docs/classes/types_errors.loginrequirederror.html
Normal file
File diff suppressed because one or more lines are too long
283
docs/classes/types_errors.notfounderror.html
Normal file
283
docs/classes/types_errors.notfounderror.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
133
docs/index.html
133
docs/index.html
File diff suppressed because one or more lines are too long
305
docs/interfaces/job_execution.jobexecutor.html
Normal file
305
docs/interfaces/job_execution.jobexecutor.html
Normal file
File diff suppressed because one or more lines are too long
200
docs/interfaces/job_execution.waitingrequstpromise.html
Normal file
200
docs/interfaces/job_execution.waitingrequstpromise.html
Normal file
File diff suppressed because one or more lines are too long
392
docs/interfaces/request.httpclient.html
Normal file
392
docs/interfaces/request.httpclient.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
209
docs/interfaces/types.logstatistics.html
Normal file
209
docs/interfaces/types.logstatistics.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
94
docs/modules/__mocks__.html
Normal file
94
docs/modules/__mocks__.html
Normal file
File diff suppressed because one or more lines are too long
179
docs/modules/auth.html
Normal file
179
docs/modules/auth.html
Normal file
File diff suppressed because one or more lines are too long
144
docs/modules/auth_spec.html
Normal file
144
docs/modules/auth_spec.html
Normal file
File diff suppressed because one or more lines are too long
184
docs/modules/file.html
Normal file
184
docs/modules/file.html
Normal file
File diff suppressed because one or more lines are too long
175
docs/modules/job_execution.html
Normal file
175
docs/modules/job_execution.html
Normal file
File diff suppressed because one or more lines are too long
106
docs/modules/reflection-817.html
Normal file
106
docs/modules/reflection-817.html
Normal file
File diff suppressed because one or more lines are too long
128
docs/modules/reflection-817.reflection-220.html
Normal file
128
docs/modules/reflection-817.reflection-220.html
Normal file
File diff suppressed because one or more lines are too long
106
docs/modules/reflection-830.html
Normal file
106
docs/modules/reflection-830.html
Normal file
File diff suppressed because one or more lines are too long
128
docs/modules/reflection-830.reflection-222.html
Normal file
128
docs/modules/reflection-830.reflection-222.html
Normal file
File diff suppressed because one or more lines are too long
118
docs/modules/request.html
Normal file
118
docs/modules/request.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
133
docs/modules/types_errors.html
Normal file
133
docs/modules/types_errors.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
188
jest.config.js
188
jest.config.js
@@ -1,10 +1,184 @@
|
||||
// For a detailed explanation regarding each configuration property, visit:
|
||||
// https://jestjs.io/docs/en/configuration.html
|
||||
|
||||
module.exports = {
|
||||
roots: ["<rootDir>/src"],
|
||||
testMatch: [
|
||||
"**/__tests__/**/*.+(ts|tsx|js)",
|
||||
"**/?(*.)+(spec|test).+(ts|tsx|js)"
|
||||
],
|
||||
testTimeout: 90000,
|
||||
// All imported modules in your tests should be mocked automatically
|
||||
// automock: false,
|
||||
|
||||
// Stop running tests after `n` failures
|
||||
// bail: 1,
|
||||
|
||||
// Respect "browser" field in package.json when resolving modules
|
||||
// browser: false,
|
||||
|
||||
// The directory where Jest should store its cached dependency information
|
||||
// cacheDirectory: "/private/var/folders/7y/nmqg1srj29q6210rs9dfsdzc0000gn/T/jest_dx",
|
||||
|
||||
// Automatically clear mock calls and instances between every test
|
||||
clearMocks: true,
|
||||
|
||||
// Indicates whether the coverage information should be collected while executing the test
|
||||
// collectCoverage: false,
|
||||
|
||||
// An array of glob patterns indicating a set of files for which coverage information should be collected
|
||||
// collectCoverageFrom: undefined,
|
||||
|
||||
// The directory where Jest should output its coverage files
|
||||
coverageDirectory: 'coverage',
|
||||
|
||||
// An array of regexp pattern strings used to skip coverage collection
|
||||
// coveragePathIgnorePatterns: [
|
||||
// "/node_modules/"
|
||||
// ],
|
||||
|
||||
// A list of reporter names that Jest uses when writing coverage reports
|
||||
// coverageReporters: [
|
||||
// "json",
|
||||
// "text",
|
||||
// "lcov",
|
||||
// "clover"
|
||||
// ],
|
||||
|
||||
// An object that configures minimum threshold enforcement for coverage results
|
||||
// coverageThreshold: undefined,
|
||||
|
||||
// A path to a custom dependency extractor
|
||||
// dependencyExtractor: undefined,
|
||||
|
||||
// Make calling deprecated APIs throw helpful error messages
|
||||
// errorOnDeprecated: false,
|
||||
|
||||
// Force coverage collection from ignored files using an array of glob patterns
|
||||
// forceCoverageMatch: [],
|
||||
|
||||
// A path to a module which exports an async function that is triggered once before all test suites
|
||||
// globalSetup: undefined,
|
||||
|
||||
// A path to a module which exports an async function that is triggered once after all test suites
|
||||
// globalTeardown: undefined,
|
||||
|
||||
// A set of global variables that need to be available in all test environments
|
||||
// globals: {},
|
||||
|
||||
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
|
||||
// maxWorkers: "50%",
|
||||
|
||||
// An array of directory names to be searched recursively up from the requiring module's location
|
||||
// moduleDirectories: [
|
||||
// "node_modules"
|
||||
// ],
|
||||
|
||||
// An array of file extensions your modules use
|
||||
// moduleFileExtensions: [
|
||||
// "js",
|
||||
// "json",
|
||||
// "jsx",
|
||||
// "ts",
|
||||
// "tsx",
|
||||
// "node"
|
||||
// ],
|
||||
|
||||
// A map from regular expressions to module names that allow to stub out resources with a single module
|
||||
moduleNameMapper: {},
|
||||
|
||||
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
|
||||
// modulePathIgnorePatterns: [],
|
||||
|
||||
// Activates notifications for test results
|
||||
// notify: false,
|
||||
|
||||
// An enum that specifies notification mode. Requires { notify: true }
|
||||
// notifyMode: "failure-change",
|
||||
|
||||
// A preset that is used as a base for Jest's configuration
|
||||
preset: 'ts-jest/presets/js-with-ts',
|
||||
|
||||
// Run tests from one or more projects
|
||||
// projects: undefined,
|
||||
|
||||
// Use this configuration option to add custom reporters to Jest
|
||||
// reporters: undefined,
|
||||
|
||||
// Automatically reset mock state between every test
|
||||
// resetMocks: false,
|
||||
|
||||
// Reset the module registry before running each individual test
|
||||
// resetModules: false,
|
||||
|
||||
// A path to a custom resolver
|
||||
// resolver: undefined,
|
||||
|
||||
// Automatically restore mock state between every test
|
||||
// restoreMocks: false,
|
||||
|
||||
// The root directory that Jest should scan for tests and modules within
|
||||
// rootDir: undefined,
|
||||
|
||||
// A list of paths to directories that Jest should use to search for files in
|
||||
// roots: [
|
||||
// "<rootDir>"
|
||||
// ],
|
||||
|
||||
// Allows you to use a custom runner instead of Jest's default test runner
|
||||
// runner: "jest-runner",
|
||||
|
||||
// The paths to modules that run some code to configure or set up the testing environment before each test
|
||||
setupFiles: [],
|
||||
|
||||
// A list of paths to modules that run some code to configure or set up the testing framework before each test
|
||||
setupFilesAfterEnv: ['jest-extended'],
|
||||
|
||||
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
|
||||
// snapshotSerializers: [],
|
||||
|
||||
// Options that will be passed to the testEnvironment
|
||||
// testEnvironmentOptions: {},
|
||||
|
||||
// Adds a location field to test results
|
||||
// testLocationInResults: false,
|
||||
|
||||
// The glob patterns Jest uses to detect test files
|
||||
testMatch: ['**/*spec.[j|t]s?(x)'],
|
||||
|
||||
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
|
||||
testPathIgnorePatterns: ['/node_modules/', '/build'],
|
||||
|
||||
// The regexp pattern or array of patterns that Jest uses to detect test files
|
||||
// testRegex: [],
|
||||
|
||||
// This option allows the use of a custom results processor
|
||||
// testResultsProcessor: undefined,
|
||||
|
||||
// This option allows use of a custom test runner
|
||||
// testRunner: "jasmine2",
|
||||
|
||||
// This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
|
||||
// testURL: "http://localhost",
|
||||
|
||||
// Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
|
||||
// timers: "real",
|
||||
|
||||
// A map from regular expressions to paths to transformers
|
||||
transform: {
|
||||
"^.+\\.(ts|tsx)$": "ts-jest"
|
||||
'^.+\\.ts?$': 'ts-jest'
|
||||
}
|
||||
};
|
||||
|
||||
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
|
||||
// transformIgnorePatterns: [
|
||||
// '**/test/**/*.ts?(x)',
|
||||
// '**/?(*.)+(spec|test).ts?(x)'
|
||||
// ]
|
||||
|
||||
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
|
||||
// unmockedModulePathPatterns: undefined,
|
||||
|
||||
// Indicates whether each individual test should be reported during the run
|
||||
// verbose: undefined,
|
||||
|
||||
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
|
||||
// watchPathIgnorePatterns: [],
|
||||
|
||||
// Whether to use watchman for file crawling
|
||||
// watchman: true,
|
||||
}
|
||||
|
||||
9172
package-lock.json
generated
9172
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
50
package.json
50
package.json
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"name": "@sasjs/adapter",
|
||||
"description": "JavaScript adapter for SAS",
|
||||
"homepage": "https://adapter.sasjs.io",
|
||||
"scripts": {
|
||||
"build": "rimraf build && rimraf node && mkdir node && cp -r src/* node && webpack && rimraf build/src && rimraf node",
|
||||
"package:lib": "npm run build && cp ./package.json build && cd build && npm version \"5.0.0\" && npm pack",
|
||||
"publish:lib": "npm run build && cd build && npm publish",
|
||||
"lint:fix": "npx prettier --write 'src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}'",
|
||||
"lint": "npx prettier --check 'src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}'",
|
||||
"test": "jest --coverage",
|
||||
"lint:fix": "npx prettier --write \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --write \"sasjs-tests/src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
||||
"lint": "npx prettier --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --check \"sasjs-tests/src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
||||
"test": "jest --silent --coverage",
|
||||
"prepublishOnly": "cp -r ./build/* . && rm -rf ./build",
|
||||
"postpublish": "git clean -fd",
|
||||
"semantic-release": "semantic-release",
|
||||
"typedoc": "typedoc"
|
||||
"typedoc": "typedoc",
|
||||
"postinstall": "[ -d .git ] && git config core.hooksPath ./.git-hooks || true"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -36,32 +38,38 @@
|
||||
},
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/isomorphic-fetch": "0.0.35",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/jest": "^26.0.23",
|
||||
"@types/mime": "^2.0.3",
|
||||
"@types/tough-cookie": "^4.0.0",
|
||||
"cp": "^0.2.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"jest": "^25.5.4",
|
||||
"dotenv": "^10.0.0",
|
||||
"jest": "^27.0.4",
|
||||
"jest-extended": "^0.11.5",
|
||||
"mime": "^2.5.2",
|
||||
"path": "^0.12.7",
|
||||
"process": "^0.11.10",
|
||||
"rimraf": "^3.0.2",
|
||||
"semantic-release": "^17.3.1",
|
||||
"terser-webpack-plugin": "^4.2.3",
|
||||
"ts-jest": "^25.5.1",
|
||||
"ts-loader": "^8.0.14",
|
||||
"semantic-release": "^17.4.4",
|
||||
"terser-webpack-plugin": "^5.1.3",
|
||||
"ts-jest": "^27.0.3",
|
||||
"ts-loader": "^9.2.2",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"typedoc": "^0.19.2",
|
||||
"typedoc-neo-theme": "^1.0.10",
|
||||
"typedoc": "^0.20.36",
|
||||
"typedoc-neo-theme": "^1.1.1",
|
||||
"typedoc-plugin-external-module-name": "^4.0.6",
|
||||
"typescript": "^3.9.7",
|
||||
"webpack": "^5.13.0",
|
||||
"webpack-cli": "^4.3.1"
|
||||
"typescript": "^4.3.2",
|
||||
"webpack": "^5.38.1",
|
||||
"webpack-cli": "^4.7.2"
|
||||
},
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@sasjs/utils": "^2.0.2",
|
||||
"es6-promise": "^4.2.8",
|
||||
"form-data": "^3.0.0",
|
||||
"@sasjs/utils": "^2.20.1",
|
||||
"axios": "^0.21.1",
|
||||
"axios-cookiejar-support": "^1.0.1",
|
||||
"form-data": "^4.0.0",
|
||||
"https": "^1.0.0",
|
||||
"isomorphic-fetch": "^2.2.1"
|
||||
"tough-cookie": "^4.0.0",
|
||||
"url": "^0.11.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": false
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ When developing on `@sasjs/adapter`, it's good practice to run the test suite ag
|
||||
|
||||
You can use the provided `update:adapter` NPM script for this.
|
||||
|
||||
```
|
||||
```bash
|
||||
npm run update:adapter
|
||||
```
|
||||
|
||||
@@ -37,7 +37,7 @@ To be able to run the `deploy` script, two environment variables need to be set:
|
||||
|
||||
So you can run the script like so:
|
||||
|
||||
```
|
||||
```bash
|
||||
SSH_ACCOUNT=me@my-sas-server.com DEPLOY_PATH=/var/www/html/my-folder/sasjs-tests npm run deploy
|
||||
```
|
||||
|
||||
@@ -49,12 +49,12 @@ The below services need to be created on your SAS server, at the location specif
|
||||
|
||||
### SAS 9
|
||||
|
||||
```
|
||||
|
||||
```sas
|
||||
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
||||
%inc mc;
|
||||
filename ft15f001 temp;
|
||||
parmcards4;
|
||||
%webout(FETCH)
|
||||
%webout(OPEN)
|
||||
%macro x();
|
||||
%do i=1 %to &_webin_file_count; %webout(OBJ,&&_webin_name&i) %end;
|
||||
@@ -63,6 +63,7 @@ parmcards4;
|
||||
;;;;
|
||||
%mm_createwebservice(path=/Public/app/common,name=sendObj)
|
||||
parmcards4;
|
||||
%webout(FETCH)
|
||||
%webout(OPEN)
|
||||
%macro x();
|
||||
%do i=1 %to &_webin_file_count; %webout(ARR,&&_webin_name&i) %end;
|
||||
@@ -70,11 +71,24 @@ parmcards4;
|
||||
%webout(CLOSE)
|
||||
;;;;
|
||||
%mm_createwebservice(path=/Public/app/common,name=sendArr)
|
||||
parmcards4;
|
||||
let he who hath understanding, reckon the number of the beast
|
||||
;;;;
|
||||
%mm_createwebservice(path=/Public/app/common,name=makeErr)
|
||||
parmcards4;
|
||||
%webout(OPEN)
|
||||
data _null_;
|
||||
file _webout;
|
||||
put ' the discovery channel ';
|
||||
run;
|
||||
%webout(CLOSE)
|
||||
;;;;
|
||||
%mm_createwebservice(path=/Public/app/common,name=invalidJSON)
|
||||
```
|
||||
|
||||
### SAS Viya
|
||||
|
||||
```
|
||||
```sas
|
||||
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
||||
%inc mc;
|
||||
filename ft15f001 temp;
|
||||
@@ -113,6 +127,15 @@ If you can trust yourself when all men doubt you,
|
||||
But make allowance for their doubting too;
|
||||
;;;;
|
||||
%mp_createwebservice(path=/Public/app/common,name=makeErr)
|
||||
parmcards4;
|
||||
%webout(OPEN)
|
||||
data _null_;
|
||||
file _webout;
|
||||
put ' the discovery channel ';
|
||||
run;
|
||||
%webout(CLOSE)
|
||||
;;;;
|
||||
%mp_createwebservice(path=/Public/app/common,name=invalidJSON)
|
||||
```
|
||||
|
||||
You should now be able to access the tests in your browser at the deployed path on your server.
|
||||
|
||||
12539
sasjs-tests/package-lock.json
generated
12539
sasjs-tests/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,21 +4,18 @@
|
||||
"homepage": ".",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@sasjs/adapter": "^1.18.2",
|
||||
"@sasjs/adapter": "file:../build/sasjs-adapter-5.0.0.tgz",
|
||||
"@sasjs/test-framework": "^1.4.0",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.5.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"@types/jest": "^26.0.3",
|
||||
"@types/node": "^14.0.14",
|
||||
"@types/react": "^16.9.41",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"@types/react-router-dom": "^5.1.5",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/node": "^14.14.41",
|
||||
"@types/react": "^17.0.1",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"@types/react-router-dom": "^5.1.7",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "3.4.1",
|
||||
"typescript": "^3.9.6"
|
||||
"react-scripts": "^4.0.2",
|
||||
"typescript": "^4.1.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
@@ -26,8 +23,8 @@
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"update:adapter": "cd .. && npm run package:lib && cd sasjs-tests && npm i ../build/sasjs-adapter-5.0.0.tgz",
|
||||
"deploy:tests": "npm run build && rsync -avhe ssh ./build/* --delete $SSH_ACCOUNT:$DEPLOY_PATH",
|
||||
"deploy": "npm run update:adapter && npm run deploy:tests"
|
||||
"deploy:tests": "rsync -avhe ssh ./build/* --delete $SSH_ACCOUNT:$DEPLOY_PATH",
|
||||
"deploy": "npm run update:adapter && npm run build && npm run deploy:tests"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
@@ -45,6 +42,6 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"node-sass": "^4.14.1"
|
||||
"node-sass": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"appLoc": "/Public/app",
|
||||
"serverType": "SASVIYA",
|
||||
"debug": false,
|
||||
"contextName": "SharedCompute",
|
||||
"contextName": "sasjs adapter compute context",
|
||||
"useComputeApi": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,39 @@
|
||||
import React, { ReactElement, useState, useContext, useEffect } from "react";
|
||||
import { TestSuiteRunner, TestSuite, AppContext } from "@sasjs/test-framework";
|
||||
import { basicTests } from "./testSuites/Basic";
|
||||
import { sendArrTests, sendObjTests } from "./testSuites/RequestData";
|
||||
import { specialCaseTests } from "./testSuites/SpecialCases";
|
||||
import { sasjsRequestTests } from "./testSuites/SasjsRequests";
|
||||
import "@sasjs/test-framework/dist/index.css";
|
||||
import { computeTests } from "./testSuites/Compute";
|
||||
import React, { ReactElement, useState, useContext, useEffect } from 'react'
|
||||
import { TestSuiteRunner, TestSuite, AppContext } from '@sasjs/test-framework'
|
||||
import { basicTests } from './testSuites/Basic'
|
||||
import { sendArrTests, sendObjTests } from './testSuites/RequestData'
|
||||
import { specialCaseTests } from './testSuites/SpecialCases'
|
||||
import { sasjsRequestTests } from './testSuites/SasjsRequests'
|
||||
import '@sasjs/test-framework/dist/index.css'
|
||||
import { computeTests } from './testSuites/Compute'
|
||||
|
||||
const App = (): ReactElement<{}> => {
|
||||
const { adapter, config } = useContext(AppContext);
|
||||
const [testSuites, setTestSuites] = useState<TestSuite[]>([]);
|
||||
const { adapter, config } = useContext(AppContext)
|
||||
const [testSuites, setTestSuites] = useState<TestSuite[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
if (adapter) {
|
||||
setTestSuites([
|
||||
const testSuites = [
|
||||
basicTests(adapter, config.userName, config.password),
|
||||
sendArrTests(adapter),
|
||||
sendObjTests(adapter),
|
||||
specialCaseTests(adapter),
|
||||
sasjsRequestTests(adapter),
|
||||
computeTests(adapter)
|
||||
]);
|
||||
sasjsRequestTests(adapter)
|
||||
]
|
||||
|
||||
if (adapter.getSasjsConfig().serverType === 'SASVIYA') {
|
||||
testSuites.push(computeTests(adapter))
|
||||
}
|
||||
|
||||
setTestSuites(testSuites)
|
||||
}
|
||||
}, [adapter, config]);
|
||||
}, [adapter, config])
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
{adapter && testSuites && <TestSuiteRunner testSuites={testSuites} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import React, { ReactElement, useState, useCallback, useContext } from "react";
|
||||
import "./Login.scss";
|
||||
import { AppContext } from "@sasjs/test-framework";
|
||||
import { Redirect } from "react-router-dom";
|
||||
import React, { ReactElement, useState, useCallback, useContext } from 'react'
|
||||
import './Login.scss'
|
||||
import { AppContext } from '@sasjs/test-framework'
|
||||
import { Redirect } from 'react-router-dom'
|
||||
|
||||
const Login = (): ReactElement<{}> => {
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const appContext = useContext(AppContext);
|
||||
const [username, setUsername] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const appContext = useContext(AppContext)
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
e.preventDefault()
|
||||
appContext.adapter.logIn(username, password).then((res) => {
|
||||
appContext.setIsLoggedIn(res.isLoggedIn);
|
||||
});
|
||||
appContext.setIsLoggedIn(res.isLoggedIn)
|
||||
})
|
||||
},
|
||||
[username, password, appContext]
|
||||
);
|
||||
)
|
||||
|
||||
return !appContext.isLoggedIn ? (
|
||||
<div className="login-container">
|
||||
@@ -48,7 +48,7 @@ const Login = (): ReactElement<{}> => {
|
||||
</div>
|
||||
) : (
|
||||
<Redirect to="/" />
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Login;
|
||||
export default Login
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import React, { ReactElement, useContext, FunctionComponent } from "react";
|
||||
import { Redirect, Route } from "react-router-dom";
|
||||
import { AppContext } from "@sasjs/test-framework";
|
||||
import React, { ReactElement, useContext, FunctionComponent } from 'react'
|
||||
import { Redirect, Route } from 'react-router-dom'
|
||||
import { AppContext } from '@sasjs/test-framework'
|
||||
|
||||
interface PrivateRouteProps {
|
||||
component: FunctionComponent;
|
||||
exact?: boolean;
|
||||
path: string;
|
||||
component: FunctionComponent
|
||||
exact?: boolean
|
||||
path: string
|
||||
}
|
||||
|
||||
const PrivateRoute = (
|
||||
props: PrivateRouteProps
|
||||
): ReactElement<PrivateRouteProps> => {
|
||||
const { component, path, exact } = props;
|
||||
const appContext = useContext(AppContext);
|
||||
const { component, path, exact } = props
|
||||
const appContext = useContext(AppContext)
|
||||
return appContext.isLoggedIn ? (
|
||||
<Route component={component} path={path} exact={exact} />
|
||||
) : (
|
||||
<Redirect to="/login" />
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default PrivateRoute;
|
||||
export default PrivateRoute
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { Route, HashRouter, Switch } from "react-router-dom";
|
||||
import "./index.scss";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import { AppProvider } from "@sasjs/test-framework";
|
||||
import PrivateRoute from "./PrivateRoute";
|
||||
import Login from "./Login";
|
||||
import App from "./App";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { Route, HashRouter, Switch } from 'react-router-dom'
|
||||
import './index.scss'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
import { AppProvider } from '@sasjs/test-framework'
|
||||
import PrivateRoute from './PrivateRoute'
|
||||
import Login from './Login'
|
||||
import App from './App'
|
||||
|
||||
ReactDOM.render(
|
||||
<AppProvider>
|
||||
@@ -17,10 +17,10 @@ ReactDOM.render(
|
||||
</Switch>
|
||||
</HashRouter>
|
||||
</AppProvider>,
|
||||
document.getElementById("root")
|
||||
);
|
||||
document.getElementById('root')
|
||||
)
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
||||
@@ -11,46 +11,46 @@
|
||||
// opt-in, read https://bit.ly/CRA-PWA
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
)
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href)
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
checkValidServiceWorker(swUrl, config)
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
"This web app is being served cache-first by a service " +
|
||||
"worker. To learn more, visit https://bit.ly/CRA-PWA"
|
||||
);
|
||||
});
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,83 +59,83 @@ function registerValidSW(swUrl, config) {
|
||||
.register(swUrl)
|
||||
.then((registration) => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
if (installingWorker == null) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the updated precached content has been fetched,
|
||||
// but the previous service worker will still serve the older
|
||||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
"New content is available and will be used when all " +
|
||||
"tabs for this page are closed. See https://bit.ly/CRA-PWA."
|
||||
);
|
||||
'New content is available and will be used when all ' +
|
||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
||||
)
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
config.onUpdate(registration)
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log("Content is cached for offline use.");
|
||||
console.log('Content is cached for offline use.')
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl, {
|
||||
headers: { "Service-Worker": "script" }
|
||||
headers: { 'Service-Worker': 'script' }
|
||||
})
|
||||
.then((response) => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get("content-type");
|
||||
const contentType = response.headers.get('content-type')
|
||||
if (
|
||||
response.status === 404 ||
|
||||
(contentType != null && contentType.indexOf("javascript") === -1)
|
||||
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready
|
||||
.then((registration) => {
|
||||
registration.unregister();
|
||||
registration.unregister()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error.message);
|
||||
});
|
||||
console.error(error.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
|
||||
@@ -1,45 +1,50 @@
|
||||
import SASjs, { ServerType, SASjsConfig } from "@sasjs/adapter";
|
||||
import { TestSuite } from "@sasjs/test-framework";
|
||||
import SASjs, { SASjsConfig } from '@sasjs/adapter'
|
||||
import { TestSuite } from '@sasjs/test-framework'
|
||||
import { ServerType } from '@sasjs/utils/types'
|
||||
|
||||
const stringData: any = { table1: [{ col1: 'first col value' }] }
|
||||
|
||||
const defaultConfig: SASjsConfig = {
|
||||
serverUrl: window.location.origin,
|
||||
pathSAS9: '/SASStoredProcess/do',
|
||||
pathSASViya: '/SASJobExecution',
|
||||
appLoc: '/Public/seedapp',
|
||||
serverType: ServerType.SASViya,
|
||||
serverType: ServerType.SasViya,
|
||||
debug: false,
|
||||
contextName: 'SAS Job Execution compute context',
|
||||
useComputeApi: false
|
||||
};
|
||||
useComputeApi: false,
|
||||
allowInsecureRequests: false
|
||||
}
|
||||
|
||||
const customConfig = {
|
||||
serverUrl: "http://url.com",
|
||||
pathSAS9: "sas9",
|
||||
pathSASViya: "viya",
|
||||
appLoc: "/Public/seedapp",
|
||||
serverType: ServerType.SAS9,
|
||||
serverUrl: 'http://url.com',
|
||||
pathSAS9: 'sas9',
|
||||
pathSASViya: 'viya',
|
||||
appLoc: '/Public/seedapp',
|
||||
serverType: ServerType.Sas9,
|
||||
debug: false
|
||||
};
|
||||
}
|
||||
|
||||
export const basicTests = (
|
||||
adapter: SASjs,
|
||||
userName: string,
|
||||
password: string
|
||||
): TestSuite => ({
|
||||
name: "Basic Tests",
|
||||
name: 'Basic Tests',
|
||||
tests: [
|
||||
{
|
||||
title: "Log in",
|
||||
description: "Should log the user in",
|
||||
title: 'Log in',
|
||||
description: 'Should log the user in',
|
||||
test: async () => {
|
||||
return adapter.logIn(userName, password);
|
||||
return adapter.logIn(userName, password)
|
||||
},
|
||||
assertion: (response: any) =>
|
||||
response && response.isLoggedIn && response.userName === userName
|
||||
},
|
||||
{
|
||||
title: "Multiple Log in attempts",
|
||||
description: "Should fail on first attempt and should log the user in on second attempt",
|
||||
title: 'Multiple Log in attempts',
|
||||
description:
|
||||
'Should fail on first attempt and should log the user in on second attempt',
|
||||
test: async () => {
|
||||
await adapter.logOut()
|
||||
await adapter.logIn('invalid', 'invalid')
|
||||
@@ -49,14 +54,49 @@ export const basicTests = (
|
||||
response && response.isLoggedIn && response.userName === userName
|
||||
},
|
||||
{
|
||||
title: "Default config",
|
||||
title: 'Trigger login callback',
|
||||
description:
|
||||
"Should instantiate with default config when none is provided",
|
||||
'Should trigger required login callback and after successful login, it should finish the request',
|
||||
test: async () => {
|
||||
return Promise.resolve(new SASjs());
|
||||
await adapter.logOut()
|
||||
|
||||
return await adapter.request(
|
||||
'common/sendArr',
|
||||
stringData,
|
||||
undefined,
|
||||
() => {
|
||||
adapter.logIn(userName, password)
|
||||
}
|
||||
)
|
||||
},
|
||||
assertion: (response: any) => {
|
||||
return response.table1[0][0] === stringData.table1[0].col1
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Request with debug on',
|
||||
description:
|
||||
'Should complete successful request with debugging switched on',
|
||||
test: async () => {
|
||||
const config = {
|
||||
debug: true
|
||||
}
|
||||
|
||||
return await adapter.request('common/sendArr', stringData, config)
|
||||
},
|
||||
assertion: (response: any) => {
|
||||
return response.table1[0][0] === stringData.table1[0].col1
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Default config',
|
||||
description:
|
||||
'Should instantiate with default config when none is provided',
|
||||
test: async () => {
|
||||
return Promise.resolve(new SASjs())
|
||||
},
|
||||
assertion: (sasjsInstance: SASjs) => {
|
||||
const sasjsConfig = sasjsInstance.getSasjsConfig();
|
||||
const sasjsConfig = sasjsInstance.getSasjsConfig()
|
||||
|
||||
return (
|
||||
sasjsConfig.serverUrl === defaultConfig.serverUrl &&
|
||||
@@ -65,17 +105,17 @@ export const basicTests = (
|
||||
sasjsConfig.appLoc === defaultConfig.appLoc &&
|
||||
sasjsConfig.serverType === defaultConfig.serverType &&
|
||||
sasjsConfig.debug === defaultConfig.debug
|
||||
);
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Custom config",
|
||||
description: "Should use fully custom config whenever supplied",
|
||||
title: 'Custom config',
|
||||
description: 'Should use fully custom config whenever supplied',
|
||||
test: async () => {
|
||||
return Promise.resolve(new SASjs(customConfig));
|
||||
return Promise.resolve(new SASjs(customConfig))
|
||||
},
|
||||
assertion: (sasjsInstance: SASjs) => {
|
||||
const sasjsConfig = sasjsInstance.getSasjsConfig();
|
||||
const sasjsConfig = sasjsInstance.getSasjsConfig()
|
||||
return (
|
||||
sasjsConfig.serverUrl === customConfig.serverUrl &&
|
||||
sasjsConfig.pathSAS9 === customConfig.pathSAS9 &&
|
||||
@@ -83,28 +123,51 @@ export const basicTests = (
|
||||
sasjsConfig.appLoc === customConfig.appLoc &&
|
||||
sasjsConfig.serverType === customConfig.serverType &&
|
||||
sasjsConfig.debug === customConfig.debug
|
||||
);
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Config overrides",
|
||||
description: "Should override default config with supplied properties",
|
||||
title: 'Config overrides',
|
||||
description: 'Should override default config with supplied properties',
|
||||
test: async () => {
|
||||
return Promise.resolve(
|
||||
new SASjs({ serverUrl: "http://test.com", debug: false })
|
||||
);
|
||||
new SASjs({ serverUrl: 'http://test.com', debug: false })
|
||||
)
|
||||
},
|
||||
assertion: (sasjsInstance: SASjs) => {
|
||||
const sasjsConfig = sasjsInstance.getSasjsConfig();
|
||||
const sasjsConfig = sasjsInstance.getSasjsConfig()
|
||||
return (
|
||||
sasjsConfig.serverUrl === "http://test.com" &&
|
||||
sasjsConfig.serverUrl === 'http://test.com' &&
|
||||
sasjsConfig.pathSAS9 === defaultConfig.pathSAS9 &&
|
||||
sasjsConfig.pathSASViya === defaultConfig.pathSASViya &&
|
||||
sasjsConfig.appLoc === defaultConfig.appLoc &&
|
||||
sasjsConfig.serverType === defaultConfig.serverType &&
|
||||
sasjsConfig.debug === false
|
||||
);
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Request with extra attributes on JES approach',
|
||||
description:
|
||||
'Should complete successful request with extra attributes present in response',
|
||||
test: async () => {
|
||||
const config = {
|
||||
useComputeApi: false
|
||||
}
|
||||
|
||||
return await adapter.request(
|
||||
'common/sendArr',
|
||||
stringData,
|
||||
config,
|
||||
undefined,
|
||||
undefined,
|
||||
['file', 'data']
|
||||
)
|
||||
},
|
||||
assertion: (response: any) => {
|
||||
const responseKeys: any = Object.keys(response)
|
||||
return responseKeys.includes('file') && responseKeys.includes('data')
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user