@laboratoria/sdk-js 0.2.0 → 1.0.0
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 +40 -3
- package/index.js +4 -5
- package/index.spec.js +12 -12
- package/lib/core.js +43 -0
- package/lib/curriculum.js +59 -0
- package/lib/curriculum.spec.js +194 -0
- package/lib/model.js +4 -31
- package/lib/model.spec.js +0 -1
- package/package.json +17 -8
- package/schemas/core.json +168 -4
- package/lib/team.js +0 -52
- package/schemas/team.json +0 -146
package/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
## Laboratoria JavaScript (browser) SDK
|
2
2
|
|
3
|
+
[](https://github.com/Laboratoria/sdk-js/actions/workflows/node.js.yml)
|
4
|
+
|
3
5
|
:warning: This tool is still in draft stage and is likely to change without
|
4
6
|
notice.
|
5
7
|
|
@@ -25,7 +27,6 @@ const app = createApp({
|
|
25
27
|
firebaseApiKey: '',
|
26
28
|
firebaseProject: '',
|
27
29
|
coreApiUrl: '',
|
28
|
-
teamApiUrl: '',
|
29
30
|
jobsApiUrl: '',
|
30
31
|
});
|
31
32
|
```
|
@@ -79,7 +80,6 @@ app.user.create({
|
|
79
80
|
### Cohorts
|
80
81
|
|
81
82
|
```js
|
82
|
-
// Cohorts API
|
83
83
|
app.cohort.findMany({
|
84
84
|
where: {
|
85
85
|
end: { gt: new Date() },
|
@@ -96,13 +96,50 @@ app.cohort.findMany({
|
|
96
96
|
|
97
97
|
### Students
|
98
98
|
|
99
|
+
WIP
|
100
|
+
|
99
101
|
### Dropouts
|
100
102
|
|
103
|
+
WIP
|
101
104
|
|
102
105
|
### Projects
|
103
106
|
|
104
107
|
```js
|
105
108
|
app.project.findMany();
|
106
109
|
|
107
|
-
|
110
|
+
app.project.findMany({ tag: 'v3.0.0' });
|
111
|
+
|
112
|
+
app.project.findMany({
|
113
|
+
locale: 'es-ES',
|
114
|
+
track: 'js',
|
115
|
+
});
|
116
|
+
|
117
|
+
app.project.findById('cipher');
|
118
|
+
|
119
|
+
app.project.findById('cipher', { tag: 'v3.0.0' });
|
108
120
|
```
|
121
|
+
|
122
|
+
### Topics
|
123
|
+
|
124
|
+
```js
|
125
|
+
app.topic.findMany();
|
126
|
+
|
127
|
+
app.topic.findMany({ tag: 'v3.0.0' });
|
128
|
+
|
129
|
+
app.topic.findMany({
|
130
|
+
locale: 'es-ES',
|
131
|
+
track: 'js',
|
132
|
+
});
|
133
|
+
|
134
|
+
app.topic.findById('javascript');
|
135
|
+
|
136
|
+
app.topic.findById('javascript', { tag: 'v3.0.0' });
|
137
|
+
```
|
138
|
+
|
139
|
+
### Learning Objectives
|
140
|
+
|
141
|
+
```js
|
142
|
+
app.learningObjective.findMany();
|
143
|
+
|
144
|
+
app.learningObjective.findMany({ tag: 'v3.0.0' });
|
145
|
+
```
|
package/index.js
CHANGED
@@ -6,14 +6,13 @@ import {
|
|
6
6
|
signOut,
|
7
7
|
} from 'firebase/auth';
|
8
8
|
import { createAPI as createCoreAPI } from './lib/core';
|
9
|
+
import { createAPI as createCurriculumAPI } from './lib/curriculum';
|
9
10
|
import { createAPI as createJobsAPI } from './lib/jobs';
|
10
|
-
import { createAPI as createTeamAPI } from './lib/team';
|
11
11
|
|
12
12
|
export const createApp = ({
|
13
13
|
firebaseApiKey = 'AIzaSyAXbaEbpq8NOfn0r8mIrcoHvoGRkJThwdc',
|
14
14
|
firebaseProject = 'laboratoria-la',
|
15
15
|
coreApiUrl = 'https://us-central1-outpost-272720.cloudfunctions.net/core-api',
|
16
|
-
teamApiUrl = 'https://us-central1-outpost-272720.cloudfunctions.net/team-api',
|
17
16
|
jobsApiUrl = 'https://us-central1-outpost-272720.cloudfunctions.net/jobs-api',
|
18
17
|
} = {}) => {
|
19
18
|
const firebaseApp = initializeApp({
|
@@ -26,8 +25,8 @@ export const createApp = ({
|
|
26
25
|
const firebaseAuth = getAuth(firebaseApp);
|
27
26
|
const state = { authUser: undefined, user: undefined };
|
28
27
|
const coreAPI = createCoreAPI(coreApiUrl, state);
|
29
|
-
const teamAPI = createTeamAPI(teamApiUrl, state);
|
30
28
|
const jobsAPI = createJobsAPI(jobsApiUrl, state);
|
29
|
+
const curriculumAPI = createCurriculumAPI();
|
31
30
|
|
32
31
|
const authAPI = {
|
33
32
|
onChange: fn => onAuthStateChanged(firebaseAuth, (authUser) => {
|
@@ -56,9 +55,9 @@ export const createApp = ({
|
|
56
55
|
};
|
57
56
|
|
58
57
|
return {
|
59
|
-
auth: authAPI,
|
60
58
|
...jobsAPI,
|
61
|
-
...
|
59
|
+
...curriculumAPI,
|
62
60
|
...coreAPI,
|
61
|
+
auth: authAPI,
|
63
62
|
};
|
64
63
|
};
|
package/index.spec.js
CHANGED
@@ -5,10 +5,16 @@ import {
|
|
5
5
|
signInWithEmailAndPassword,
|
6
6
|
signOut,
|
7
7
|
} from 'firebase/auth';
|
8
|
-
import {
|
8
|
+
import { createAPI as createCoreAPI } from './lib/core';
|
9
9
|
import { createApp } from './index.js';
|
10
10
|
|
11
|
-
jest.mock('./lib/
|
11
|
+
jest.mock('./lib/core.js', () => ({
|
12
|
+
createAPI: jest.fn().mockReturnValue({
|
13
|
+
user: {
|
14
|
+
findById: jest.fn().mockResolvedValue({}),
|
15
|
+
},
|
16
|
+
}),
|
17
|
+
}));
|
12
18
|
|
13
19
|
beforeEach(() => {
|
14
20
|
initializeApp.mockClear();
|
@@ -40,7 +46,7 @@ describe('app.auth.onChange', () => {
|
|
40
46
|
});
|
41
47
|
});
|
42
48
|
|
43
|
-
it('should fetch user from db when authenticated
|
49
|
+
it('should fetch user from db when authenticated using coreAPI', (done) => {
|
44
50
|
const { auth } = createApp();
|
45
51
|
const mockAuthUser = { uid: 'xxx', getIdToken: () => 'token' };
|
46
52
|
const userMock = { uid: 'xxx', email: 'foo@bar.baz' };
|
@@ -50,17 +56,11 @@ describe('app.auth.onChange', () => {
|
|
50
56
|
return () => { };
|
51
57
|
});
|
52
58
|
|
53
|
-
|
59
|
+
createCoreAPI().user.findById.mockResolvedValue(userMock);
|
54
60
|
|
55
61
|
auth.onChange(({ authUser, user }) => {
|
56
62
|
expect(authUser).toEqual(mockAuthUser);
|
57
|
-
expect(user).toEqual(
|
58
|
-
...userMock,
|
59
|
-
isStaff: false,
|
60
|
-
isManager: false,
|
61
|
-
isFinance: false,
|
62
|
-
isAdmin: false,
|
63
|
-
});
|
63
|
+
expect(user).toEqual(userMock);
|
64
64
|
done();
|
65
65
|
});
|
66
66
|
});
|
@@ -76,7 +76,7 @@ describe('app.auth.onChange', () => {
|
|
76
76
|
return () => { };
|
77
77
|
});
|
78
78
|
|
79
|
-
|
79
|
+
createCoreAPI().user.findById.mockRejectedValueOnce(error);
|
80
80
|
|
81
81
|
auth.onChange(({ authUser, user }) => {
|
82
82
|
expect(authUser).toBeNull();
|
package/lib/core.js
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
import md5 from 'blueimp-md5';
|
2
|
+
import currencies from './currencies';
|
3
|
+
import roles from './roles';
|
2
4
|
import { createModels, extendSchemaDefinitions } from './model';
|
3
5
|
import schema from '../schemas/core.json';
|
4
6
|
|
5
7
|
const extended = {
|
8
|
+
Country: {
|
9
|
+
plural: 'countries',
|
10
|
+
},
|
6
11
|
User: {
|
7
12
|
primaryKey: 'uid',
|
8
13
|
inputProps: [
|
@@ -69,6 +74,7 @@ const extended = {
|
|
69
74
|
properties: {},
|
70
75
|
parse: (props) => {
|
71
76
|
const now = Date.now();
|
77
|
+
// TODO: Handle case where start and/or end have not been selected in query
|
72
78
|
const status = (
|
73
79
|
props.start > now
|
74
80
|
? 'upcoming'
|
@@ -113,6 +119,43 @@ const extended = {
|
|
113
119
|
'cohort.name',
|
114
120
|
],
|
115
121
|
},
|
122
|
+
Contract: {
|
123
|
+
inputProps: [
|
124
|
+
'user',
|
125
|
+
'countryCode',
|
126
|
+
'currency',
|
127
|
+
'isEmployment',
|
128
|
+
'feeBasis',
|
129
|
+
'feeAmount',
|
130
|
+
'hoursPerWeek',
|
131
|
+
'start',
|
132
|
+
'end',
|
133
|
+
],
|
134
|
+
properties: {
|
135
|
+
countryCode: {
|
136
|
+
enum: ['BR', 'CL', 'CO', 'MX', 'PE'],
|
137
|
+
},
|
138
|
+
currency: {
|
139
|
+
enum: currencies,
|
140
|
+
},
|
141
|
+
},
|
142
|
+
},
|
143
|
+
Gig: {
|
144
|
+
inputProps: [
|
145
|
+
// 'contract',
|
146
|
+
'cohort',
|
147
|
+
'user',
|
148
|
+
'role',
|
149
|
+
'hoursPerWeek',
|
150
|
+
'start',
|
151
|
+
'end',
|
152
|
+
],
|
153
|
+
properties: {
|
154
|
+
role: {
|
155
|
+
enum: roles,
|
156
|
+
},
|
157
|
+
},
|
158
|
+
},
|
116
159
|
};
|
117
160
|
|
118
161
|
export const createAPI = (url, state) => createModels(url, state, {
|
@@ -0,0 +1,59 @@
|
|
1
|
+
const releasesUrl = 'https://api.github.com/repos/Laboratoria/bootcamp/releases';
|
2
|
+
const rawUrl = 'https://raw.githubusercontent.com/Laboratoria/bootcamp';
|
3
|
+
|
4
|
+
const getLatestVersion = () => fetch(`${releasesUrl}/latest`)
|
5
|
+
.then(resp => resp.json())
|
6
|
+
.then(({ tag_name }) => tag_name);
|
7
|
+
|
8
|
+
const fetchProjects = async tag => (
|
9
|
+
fetch(`${rawUrl}/${tag || await getLatestVersion()}/dist/projects.json`)
|
10
|
+
.then(resp => resp.json())
|
11
|
+
);
|
12
|
+
|
13
|
+
const fetchProject = async (slug, tag) => (
|
14
|
+
fetch(`${rawUrl}/${tag || await getLatestVersion()}/dist/projects/${slug}.json`)
|
15
|
+
.then(resp => resp.json())
|
16
|
+
);
|
17
|
+
|
18
|
+
const fetchTopics = async tag => (
|
19
|
+
fetch(`${rawUrl}/${tag || await getLatestVersion()}/dist/topics.json`)
|
20
|
+
.then(resp => resp.json())
|
21
|
+
);
|
22
|
+
|
23
|
+
const fetchTopic = async (slug, tag) => (
|
24
|
+
fetch(`${rawUrl}/${tag || await getLatestVersion()}/dist/topics/${slug}.json`)
|
25
|
+
.then(resp => resp.json())
|
26
|
+
);
|
27
|
+
|
28
|
+
const fetchLearningObjectives = async tag => (
|
29
|
+
fetch(`${rawUrl}/${tag || await getLatestVersion()}/dist/learning-objectives.json`)
|
30
|
+
.then(resp => resp.json())
|
31
|
+
);
|
32
|
+
|
33
|
+
const filterByLocaleAndTrack = opts => arr => arr.filter((obj) => {
|
34
|
+
if (opts.locale && opts.locale !== obj.locale) {
|
35
|
+
return false;
|
36
|
+
}
|
37
|
+
if (opts.track && opts.track !== obj.track) {
|
38
|
+
return false;
|
39
|
+
}
|
40
|
+
return true;
|
41
|
+
});
|
42
|
+
|
43
|
+
export const createAPI = () => {
|
44
|
+
return {
|
45
|
+
projects: {
|
46
|
+
findMany: (opts = {}) => fetchProjects(opts.tag)
|
47
|
+
.then(filterByLocaleAndTrack(opts)),
|
48
|
+
findById: (slug, opts = {}) => fetchProject(slug, opts.tag),
|
49
|
+
},
|
50
|
+
topics: {
|
51
|
+
findMany: (opts = {}) => fetchTopics(opts.tag)
|
52
|
+
.then(filterByLocaleAndTrack(opts)),
|
53
|
+
findById: (slug, opts = {}) => fetchTopic(slug, opts.tag),
|
54
|
+
},
|
55
|
+
learningObjectives: {
|
56
|
+
findMany: (opts = {}) => fetchLearningObjectives(opts.tag),
|
57
|
+
},
|
58
|
+
};
|
59
|
+
};
|
@@ -0,0 +1,194 @@
|
|
1
|
+
import { createAPI } from './curriculum';
|
2
|
+
|
3
|
+
describe('projects', () => {
|
4
|
+
describe('findMany', () => {
|
5
|
+
// TODO: errores HTTP, GitHub caido, repo borrado, etc...
|
6
|
+
|
7
|
+
it('sends request to get latest version and then corresponding json', () => {
|
8
|
+
global.fetch = jest.fn().mockImplementation(async url => ({
|
9
|
+
status: 200,
|
10
|
+
json: jest.fn().mockResolvedValue(
|
11
|
+
url.startsWith('https://api.')
|
12
|
+
? { tag_name: 'v4.0.0' }
|
13
|
+
: []
|
14
|
+
),
|
15
|
+
}));
|
16
|
+
|
17
|
+
return createAPI().projects.findMany()
|
18
|
+
.then((projects) => {
|
19
|
+
expect(projects).toEqual([]);
|
20
|
+
expect(global.fetch).toHaveBeenCalledTimes(2);
|
21
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
22
|
+
1,
|
23
|
+
'https://api.github.com/repos/Laboratoria/bootcamp/releases/latest',
|
24
|
+
);
|
25
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
26
|
+
2,
|
27
|
+
'https://raw.githubusercontent.com/Laboratoria/bootcamp/v4.0.0/dist/projects.json',
|
28
|
+
);
|
29
|
+
});
|
30
|
+
});
|
31
|
+
|
32
|
+
it('gets projects in specific tag when passed as option', () => {
|
33
|
+
global.fetch = jest.fn().mockImplementation(async url => ({
|
34
|
+
status: 200,
|
35
|
+
json: jest.fn().mockResolvedValue(
|
36
|
+
url.startsWith('https://api.')
|
37
|
+
? { tag_name: 'v4.0.0' }
|
38
|
+
: []
|
39
|
+
),
|
40
|
+
}));
|
41
|
+
|
42
|
+
return createAPI().projects.findMany({ tag: 'v3.0.0' })
|
43
|
+
.then((projects) => {
|
44
|
+
expect(projects).toEqual([]);
|
45
|
+
expect(global.fetch).toHaveBeenCalledTimes(1);
|
46
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
47
|
+
'https://raw.githubusercontent.com/Laboratoria/bootcamp/v3.0.0/dist/projects.json',
|
48
|
+
);
|
49
|
+
});
|
50
|
+
});
|
51
|
+
|
52
|
+
it('gets projects in specific tag when passed as option', () => {
|
53
|
+
global.fetch = jest.fn().mockImplementation(async url => ({
|
54
|
+
status: 200,
|
55
|
+
json: jest.fn().mockResolvedValue(
|
56
|
+
url.startsWith('https://api.')
|
57
|
+
? { tag_name: 'v4.0.0' }
|
58
|
+
: [
|
59
|
+
{ locale: 'es-ES', track: 'ux' },
|
60
|
+
{ locale: 'es-ES', track: 'js' },
|
61
|
+
{ locale: 'pt-BR', track: 'ux' },
|
62
|
+
]
|
63
|
+
),
|
64
|
+
}));
|
65
|
+
|
66
|
+
return createAPI().projects.findMany({
|
67
|
+
tag: 'v3.0.0',
|
68
|
+
locale: 'es-ES',
|
69
|
+
track: 'ux',
|
70
|
+
})
|
71
|
+
.then((projects) => {
|
72
|
+
expect(projects).toEqual([{ locale: 'es-ES', track: 'ux' }]);
|
73
|
+
expect(global.fetch).toHaveBeenCalledTimes(1);
|
74
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
75
|
+
'https://raw.githubusercontent.com/Laboratoria/bootcamp/v3.0.0/dist/projects.json',
|
76
|
+
);
|
77
|
+
});
|
78
|
+
});
|
79
|
+
|
80
|
+
// it should filter by tag, locale and track...
|
81
|
+
});
|
82
|
+
|
83
|
+
describe('findById', () => {
|
84
|
+
it('sends request to get latest version and then corresponding json', () => {
|
85
|
+
global.fetch = jest.fn().mockImplementation(async url => ({
|
86
|
+
status: 200,
|
87
|
+
json: jest.fn().mockResolvedValue(
|
88
|
+
url.startsWith('https://api.')
|
89
|
+
? { tag_name: 'v4.0.0' }
|
90
|
+
: {}
|
91
|
+
),
|
92
|
+
}));
|
93
|
+
|
94
|
+
return createAPI().projects.findById('cipher')
|
95
|
+
.then((project) => {
|
96
|
+
expect(project).toEqual({});
|
97
|
+
expect(global.fetch).toHaveBeenCalledTimes(2);
|
98
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
99
|
+
1,
|
100
|
+
'https://api.github.com/repos/Laboratoria/bootcamp/releases/latest',
|
101
|
+
);
|
102
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
103
|
+
2,
|
104
|
+
'https://raw.githubusercontent.com/Laboratoria/bootcamp/v4.0.0/dist/projects/cipher.json',
|
105
|
+
);
|
106
|
+
});
|
107
|
+
});
|
108
|
+
});
|
109
|
+
});
|
110
|
+
|
111
|
+
describe('topics', () => {
|
112
|
+
describe('findMany', () => {
|
113
|
+
it('sends request to get latest version and then corresponding json', () => {
|
114
|
+
global.fetch = jest.fn().mockImplementation(async url => ({
|
115
|
+
status: 200,
|
116
|
+
json: jest.fn().mockResolvedValue(
|
117
|
+
url.startsWith('https://api.')
|
118
|
+
? { tag_name: 'v4.0.0' }
|
119
|
+
: []
|
120
|
+
),
|
121
|
+
}));
|
122
|
+
|
123
|
+
return createAPI().topics.findMany()
|
124
|
+
.then((topics) => {
|
125
|
+
expect(topics).toEqual([]);
|
126
|
+
expect(global.fetch).toHaveBeenCalledTimes(2);
|
127
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
128
|
+
1,
|
129
|
+
'https://api.github.com/repos/Laboratoria/bootcamp/releases/latest',
|
130
|
+
);
|
131
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
132
|
+
2,
|
133
|
+
'https://raw.githubusercontent.com/Laboratoria/bootcamp/v4.0.0/dist/topics.json',
|
134
|
+
);
|
135
|
+
});
|
136
|
+
});
|
137
|
+
});
|
138
|
+
|
139
|
+
describe('findById', () => {
|
140
|
+
it('sends request to get latest version and then corresponding json', () => {
|
141
|
+
global.fetch = jest.fn().mockImplementation(async url => ({
|
142
|
+
status: 200,
|
143
|
+
json: jest.fn().mockResolvedValue(
|
144
|
+
url.startsWith('https://api.')
|
145
|
+
? { tag_name: 'v4.0.0' }
|
146
|
+
: {}
|
147
|
+
),
|
148
|
+
}));
|
149
|
+
|
150
|
+
return createAPI().topics.findById('javascript')
|
151
|
+
.then((topic) => {
|
152
|
+
expect(topic).toEqual({});
|
153
|
+
expect(global.fetch).toHaveBeenCalledTimes(2);
|
154
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
155
|
+
1,
|
156
|
+
'https://api.github.com/repos/Laboratoria/bootcamp/releases/latest',
|
157
|
+
);
|
158
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
159
|
+
2,
|
160
|
+
'https://raw.githubusercontent.com/Laboratoria/bootcamp/v4.0.0/dist/topics/javascript.json',
|
161
|
+
);
|
162
|
+
});
|
163
|
+
});
|
164
|
+
});
|
165
|
+
});
|
166
|
+
|
167
|
+
describe('learningObjectives', () => {
|
168
|
+
describe('findMany', () => {
|
169
|
+
it('sends request to get latest version and then corresponding json', () => {
|
170
|
+
global.fetch = jest.fn().mockImplementation(async url => ({
|
171
|
+
status: 200,
|
172
|
+
json: jest.fn().mockResolvedValue(
|
173
|
+
url.startsWith('https://api.')
|
174
|
+
? { tag_name: 'v4.0.0' }
|
175
|
+
: []
|
176
|
+
),
|
177
|
+
}));
|
178
|
+
|
179
|
+
return createAPI().learningObjectives.findMany()
|
180
|
+
.then((learningObjectives) => {
|
181
|
+
expect(learningObjectives).toEqual([]);
|
182
|
+
expect(global.fetch).toHaveBeenCalledTimes(2);
|
183
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
184
|
+
1,
|
185
|
+
'https://api.github.com/repos/Laboratoria/bootcamp/releases/latest',
|
186
|
+
);
|
187
|
+
expect(global.fetch).toHaveBeenNthCalledWith(
|
188
|
+
2,
|
189
|
+
'https://raw.githubusercontent.com/Laboratoria/bootcamp/v4.0.0/dist/learning-objectives.json',
|
190
|
+
);
|
191
|
+
});
|
192
|
+
});
|
193
|
+
});
|
194
|
+
});
|
package/lib/model.js
CHANGED
@@ -71,28 +71,6 @@ const createBuildURL = collectionName => (id, q) => {
|
|
71
71
|
};
|
72
72
|
|
73
73
|
|
74
|
-
const createBuildQuery = defaultInclude => (q = {}) => ({
|
75
|
-
...(!q.select && Object.keys(defaultInclude).length && { include: defaultInclude }),
|
76
|
-
...q,
|
77
|
-
});
|
78
|
-
|
79
|
-
|
80
|
-
const buildDefaultInclude = schema => Object.keys(schema.properties || {}).reduce(
|
81
|
-
(memo, key) => (
|
82
|
-
(
|
83
|
-
schema.properties[key].$ref
|
84
|
-
|| (
|
85
|
-
Array.isArray(schema.properties[key].anyOf)
|
86
|
-
&& schema.properties[key].anyOf[0].$ref
|
87
|
-
)
|
88
|
-
)
|
89
|
-
? { ...memo, [key]: true }
|
90
|
-
: memo
|
91
|
-
),
|
92
|
-
{},
|
93
|
-
);
|
94
|
-
|
95
|
-
|
96
74
|
const serializeData = (data, schema) => {
|
97
75
|
const hasInputProps = Array.isArray(schema.inputProps);
|
98
76
|
const payload = Object.keys(data).reduce(
|
@@ -133,17 +111,15 @@ export const createModel = (baseUrl, state, collectionName, schema = {}) => {
|
|
133
111
|
const primaryKey = schema.primaryKey || 'id';
|
134
112
|
const validator = createValidator(schema);
|
135
113
|
const buildURL = createBuildURL(collectionName);
|
136
|
-
const defaultInclude = buildDefaultInclude(schema);
|
137
|
-
const buildQuery = createBuildQuery(defaultInclude);
|
138
114
|
const req = (...args) => createClient(baseUrl, state.authUser)(...args);
|
139
115
|
const create = q => req(buildURL(), {
|
140
116
|
method: 'POST',
|
141
|
-
body:
|
117
|
+
body: Object.assign(q, { data: serializeData(q.data, schema) }),
|
142
118
|
});
|
143
119
|
|
144
120
|
const put = q => req(buildURL(q.where[primaryKey]), {
|
145
121
|
method: 'PUT',
|
146
|
-
body:
|
122
|
+
body: Object.assign(q, { data: serializeData(q.data, schema) }),
|
147
123
|
});
|
148
124
|
|
149
125
|
const parse = data => {
|
@@ -172,14 +148,11 @@ export const createModel = (baseUrl, state, collectionName, schema = {}) => {
|
|
172
148
|
get schema() {
|
173
149
|
return schema;
|
174
150
|
},
|
175
|
-
get include() {
|
176
|
-
return defaultInclude;
|
177
|
-
},
|
178
151
|
validateAttr: validator.validateAttr,
|
179
152
|
validate: validator.validate,
|
180
|
-
findMany: q => req(buildURL(null,
|
153
|
+
findMany: q => req(buildURL(null, q))
|
181
154
|
.then(results => results.map(parse)),
|
182
|
-
findById: (id, q) => req(buildURL(id,
|
155
|
+
findById: (id, q) => req(buildURL(id, q))
|
183
156
|
.then(raw => !!raw ? parse(raw) : raw),
|
184
157
|
create,
|
185
158
|
update: put,
|
package/lib/model.spec.js
CHANGED
package/package.json
CHANGED
@@ -1,24 +1,33 @@
|
|
1
1
|
{
|
2
2
|
"name": "@laboratoria/sdk-js",
|
3
|
-
"version": "0.
|
3
|
+
"version": "1.0.0",
|
4
4
|
"description": "Laboratoria JavaScript (browser) SDK",
|
5
5
|
"scripts": {
|
6
|
-
"test": "jest --verbose --coverage"
|
6
|
+
"test": "jest --verbose --coverage",
|
7
|
+
"changelog": "git log $(git describe --tags --abbrev=0)..HEAD --oneline --format=\"* %h %s (%an)\""
|
7
8
|
},
|
8
9
|
"license": "MIT",
|
9
10
|
"dependencies": {
|
10
11
|
"blueimp-md5": "^2.19.0",
|
11
|
-
"firebase": "^9.6.
|
12
|
+
"firebase": "^9.6.4"
|
12
13
|
},
|
13
14
|
"devDependencies": {
|
14
|
-
"@babel/core": "^7.16.
|
15
|
+
"@babel/core": "^7.16.12",
|
15
16
|
"@babel/plugin-transform-modules-commonjs": "^7.16.8",
|
16
17
|
"babel-jest": "^27.4.6",
|
17
18
|
"jest": "^27.4.7",
|
18
|
-
"webpack": "^5.
|
19
|
-
"webpack-cli": "^4.9.
|
19
|
+
"webpack": "^5.67.0",
|
20
|
+
"webpack-cli": "^4.9.2"
|
20
21
|
},
|
21
22
|
"jest": {
|
22
|
-
"testEnvironment": "jsdom"
|
23
|
+
"testEnvironment": "jsdom",
|
24
|
+
"coverageThreshold": {
|
25
|
+
"global": {
|
26
|
+
"statements": 96,
|
27
|
+
"branches": 91,
|
28
|
+
"functions": 98,
|
29
|
+
"lines": 96
|
30
|
+
}
|
31
|
+
}
|
23
32
|
}
|
24
|
-
}
|
33
|
+
}
|
package/schemas/core.json
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
{
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
3
3
|
"definitions": {
|
4
|
+
"Country": {
|
5
|
+
"type": "object",
|
6
|
+
"properties": {
|
7
|
+
"code": {
|
8
|
+
"type": "string"
|
9
|
+
},
|
10
|
+
"name": {
|
11
|
+
"type": "string"
|
12
|
+
},
|
13
|
+
"contracts": {
|
14
|
+
"type": "array",
|
15
|
+
"items": {
|
16
|
+
"$ref": "#/definitions/Contract"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
},
|
4
21
|
"User": {
|
5
22
|
"type": "object",
|
6
23
|
"properties": {
|
@@ -99,6 +116,18 @@
|
|
99
116
|
"type": "null"
|
100
117
|
}
|
101
118
|
]
|
119
|
+
},
|
120
|
+
"contracts": {
|
121
|
+
"type": "array",
|
122
|
+
"items": {
|
123
|
+
"$ref": "#/definitions/Contract"
|
124
|
+
}
|
125
|
+
},
|
126
|
+
"gigs": {
|
127
|
+
"type": "array",
|
128
|
+
"items": {
|
129
|
+
"$ref": "#/definitions/Gig"
|
130
|
+
}
|
102
131
|
}
|
103
132
|
}
|
104
133
|
},
|
@@ -270,20 +299,26 @@
|
|
270
299
|
"$ref": "#/definitions/Dropout"
|
271
300
|
}
|
272
301
|
},
|
302
|
+
"gigs": {
|
303
|
+
"type": "array",
|
304
|
+
"items": {
|
305
|
+
"$ref": "#/definitions/Gig"
|
306
|
+
}
|
307
|
+
},
|
273
308
|
"links": {
|
274
309
|
"type": "array",
|
275
310
|
"items": {
|
276
311
|
"$ref": "#/definitions/CohortLink"
|
277
312
|
}
|
278
313
|
},
|
279
|
-
"legacySlug": {
|
280
|
-
"type": "string"
|
281
|
-
},
|
282
314
|
"signupUsers": {
|
283
315
|
"type": "array",
|
284
316
|
"items": {
|
285
317
|
"$ref": "#/definitions/User"
|
286
318
|
}
|
319
|
+
},
|
320
|
+
"legacySlug": {
|
321
|
+
"type": "string"
|
287
322
|
}
|
288
323
|
}
|
289
324
|
},
|
@@ -307,7 +342,7 @@
|
|
307
342
|
"null"
|
308
343
|
]
|
309
344
|
},
|
310
|
-
"
|
345
|
+
"legacyStudentCode": {
|
311
346
|
"type": [
|
312
347
|
"string",
|
313
348
|
"null"
|
@@ -415,10 +450,133 @@
|
|
415
450
|
"$ref": "#/definitions/User"
|
416
451
|
}
|
417
452
|
}
|
453
|
+
},
|
454
|
+
"Contract": {
|
455
|
+
"type": "object",
|
456
|
+
"properties": {
|
457
|
+
"id": {
|
458
|
+
"type": "integer"
|
459
|
+
},
|
460
|
+
"createdAt": {
|
461
|
+
"type": "string",
|
462
|
+
"format": "date-time"
|
463
|
+
},
|
464
|
+
"updatedAt": {
|
465
|
+
"type": "string",
|
466
|
+
"format": "date-time"
|
467
|
+
},
|
468
|
+
"createdBy": {
|
469
|
+
"type": "string"
|
470
|
+
},
|
471
|
+
"start": {
|
472
|
+
"type": "string",
|
473
|
+
"format": "date-time"
|
474
|
+
},
|
475
|
+
"end": {
|
476
|
+
"type": [
|
477
|
+
"string",
|
478
|
+
"null"
|
479
|
+
],
|
480
|
+
"format": "date-time"
|
481
|
+
},
|
482
|
+
"hoursPerWeek": {
|
483
|
+
"type": "integer"
|
484
|
+
},
|
485
|
+
"isEmployment": {
|
486
|
+
"type": "boolean"
|
487
|
+
},
|
488
|
+
"currency": {
|
489
|
+
"type": "string",
|
490
|
+
"enum": [
|
491
|
+
"BRL",
|
492
|
+
"CLP",
|
493
|
+
"COP",
|
494
|
+
"MXN",
|
495
|
+
"PEN",
|
496
|
+
"USD"
|
497
|
+
]
|
498
|
+
},
|
499
|
+
"feeBasis": {
|
500
|
+
"type": "string",
|
501
|
+
"enum": [
|
502
|
+
"HOURLY",
|
503
|
+
"MONTHLY"
|
504
|
+
]
|
505
|
+
},
|
506
|
+
"feeAmount": {
|
507
|
+
"type": "integer"
|
508
|
+
},
|
509
|
+
"user": {
|
510
|
+
"$ref": "#/definitions/User"
|
511
|
+
},
|
512
|
+
"country": {
|
513
|
+
"$ref": "#/definitions/Country"
|
514
|
+
},
|
515
|
+
"gigs": {
|
516
|
+
"type": "array",
|
517
|
+
"items": {
|
518
|
+
"$ref": "#/definitions/Gig"
|
519
|
+
}
|
520
|
+
}
|
521
|
+
}
|
522
|
+
},
|
523
|
+
"Gig": {
|
524
|
+
"type": "object",
|
525
|
+
"properties": {
|
526
|
+
"id": {
|
527
|
+
"type": "integer"
|
528
|
+
},
|
529
|
+
"createdAt": {
|
530
|
+
"type": "string",
|
531
|
+
"format": "date-time"
|
532
|
+
},
|
533
|
+
"updatedAt": {
|
534
|
+
"type": "string",
|
535
|
+
"format": "date-time"
|
536
|
+
},
|
537
|
+
"createdBy": {
|
538
|
+
"type": "string"
|
539
|
+
},
|
540
|
+
"start": {
|
541
|
+
"type": "string",
|
542
|
+
"format": "date-time"
|
543
|
+
},
|
544
|
+
"end": {
|
545
|
+
"type": [
|
546
|
+
"string",
|
547
|
+
"null"
|
548
|
+
],
|
549
|
+
"format": "date-time"
|
550
|
+
},
|
551
|
+
"hoursPerWeek": {
|
552
|
+
"type": "integer"
|
553
|
+
},
|
554
|
+
"role": {
|
555
|
+
"type": "string",
|
556
|
+
"enum": [
|
557
|
+
"bm",
|
558
|
+
"pdc",
|
559
|
+
"js",
|
560
|
+
"ux"
|
561
|
+
]
|
562
|
+
},
|
563
|
+
"user": {
|
564
|
+
"$ref": "#/definitions/User"
|
565
|
+
},
|
566
|
+
"contract": {
|
567
|
+
"$ref": "#/definitions/Contract"
|
568
|
+
},
|
569
|
+
"cohort": {
|
570
|
+
"$ref": "#/definitions/Cohort"
|
571
|
+
}
|
572
|
+
}
|
418
573
|
}
|
419
574
|
},
|
420
575
|
"type": "object",
|
421
576
|
"properties": {
|
577
|
+
"country": {
|
578
|
+
"$ref": "#/definitions/Country"
|
579
|
+
},
|
422
580
|
"user": {
|
423
581
|
"$ref": "#/definitions/User"
|
424
582
|
},
|
@@ -442,6 +600,12 @@
|
|
442
600
|
},
|
443
601
|
"dropout": {
|
444
602
|
"$ref": "#/definitions/Dropout"
|
603
|
+
},
|
604
|
+
"contract": {
|
605
|
+
"$ref": "#/definitions/Contract"
|
606
|
+
},
|
607
|
+
"gig": {
|
608
|
+
"$ref": "#/definitions/Gig"
|
445
609
|
}
|
446
610
|
}
|
447
611
|
}
|
package/lib/team.js
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
import { createModels, extendSchemaDefinitions } from './model';
|
2
|
-
import currencies from './currencies';
|
3
|
-
import roles from './roles';
|
4
|
-
import schema from '../schemas/team.json';
|
5
|
-
|
6
|
-
const extended = {
|
7
|
-
Country: {
|
8
|
-
plural: 'countries',
|
9
|
-
},
|
10
|
-
Contract: {
|
11
|
-
inputProps: [
|
12
|
-
'uid',
|
13
|
-
'countryCode',
|
14
|
-
'currency',
|
15
|
-
'isEmployment',
|
16
|
-
'feeBasis',
|
17
|
-
'feeAmount',
|
18
|
-
'hoursPerWeek',
|
19
|
-
'start',
|
20
|
-
'end',
|
21
|
-
],
|
22
|
-
properties: {
|
23
|
-
countryCode: {
|
24
|
-
enum: ['BR', 'CL', 'CO', 'MX', 'PE'],
|
25
|
-
},
|
26
|
-
currency: {
|
27
|
-
enum: currencies,
|
28
|
-
},
|
29
|
-
},
|
30
|
-
},
|
31
|
-
Gig: {
|
32
|
-
inputProps: [
|
33
|
-
// 'contract',
|
34
|
-
'cohortId',
|
35
|
-
'uid',
|
36
|
-
'role',
|
37
|
-
'hoursPerWeek',
|
38
|
-
'start',
|
39
|
-
'end',
|
40
|
-
],
|
41
|
-
properties: {
|
42
|
-
role: {
|
43
|
-
enum: roles,
|
44
|
-
},
|
45
|
-
},
|
46
|
-
},
|
47
|
-
};
|
48
|
-
|
49
|
-
export const createAPI = (url, state) => createModels(url, state, {
|
50
|
-
...schema,
|
51
|
-
definitions: extendSchemaDefinitions(schema, extended),
|
52
|
-
});
|
package/schemas/team.json
DELETED
@@ -1,146 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
3
|
-
"definitions": {
|
4
|
-
"Country": {
|
5
|
-
"type": "object",
|
6
|
-
"properties": {
|
7
|
-
"code": {
|
8
|
-
"type": "string"
|
9
|
-
},
|
10
|
-
"name": {
|
11
|
-
"type": "string"
|
12
|
-
},
|
13
|
-
"contracts": {
|
14
|
-
"type": "array",
|
15
|
-
"items": {
|
16
|
-
"$ref": "#/definitions/Contract"
|
17
|
-
}
|
18
|
-
}
|
19
|
-
}
|
20
|
-
},
|
21
|
-
"Contract": {
|
22
|
-
"type": "object",
|
23
|
-
"properties": {
|
24
|
-
"id": {
|
25
|
-
"type": "integer"
|
26
|
-
},
|
27
|
-
"createdAt": {
|
28
|
-
"type": "string",
|
29
|
-
"format": "date-time"
|
30
|
-
},
|
31
|
-
"updatedAt": {
|
32
|
-
"type": "string",
|
33
|
-
"format": "date-time"
|
34
|
-
},
|
35
|
-
"createdBy": {
|
36
|
-
"type": "string"
|
37
|
-
},
|
38
|
-
"uid": {
|
39
|
-
"type": "string"
|
40
|
-
},
|
41
|
-
"isEmployment": {
|
42
|
-
"type": "boolean"
|
43
|
-
},
|
44
|
-
"currency": {
|
45
|
-
"type": "string"
|
46
|
-
},
|
47
|
-
"feeBasis": {
|
48
|
-
"type": "string",
|
49
|
-
"enum": [
|
50
|
-
"HOURLY",
|
51
|
-
"MONTHLY"
|
52
|
-
]
|
53
|
-
},
|
54
|
-
"feeAmount": {
|
55
|
-
"type": "integer"
|
56
|
-
},
|
57
|
-
"hoursPerWeek": {
|
58
|
-
"type": "integer"
|
59
|
-
},
|
60
|
-
"start": {
|
61
|
-
"type": "string",
|
62
|
-
"format": "date-time"
|
63
|
-
},
|
64
|
-
"end": {
|
65
|
-
"type": [
|
66
|
-
"string",
|
67
|
-
"null"
|
68
|
-
],
|
69
|
-
"format": "date-time"
|
70
|
-
},
|
71
|
-
"country": {
|
72
|
-
"$ref": "#/definitions/Country"
|
73
|
-
},
|
74
|
-
"gigs": {
|
75
|
-
"type": "array",
|
76
|
-
"items": {
|
77
|
-
"$ref": "#/definitions/Gig"
|
78
|
-
}
|
79
|
-
}
|
80
|
-
}
|
81
|
-
},
|
82
|
-
"Gig": {
|
83
|
-
"type": "object",
|
84
|
-
"properties": {
|
85
|
-
"id": {
|
86
|
-
"type": "integer"
|
87
|
-
},
|
88
|
-
"createdAt": {
|
89
|
-
"type": "string",
|
90
|
-
"format": "date-time"
|
91
|
-
},
|
92
|
-
"updatedAt": {
|
93
|
-
"type": "string",
|
94
|
-
"format": "date-time"
|
95
|
-
},
|
96
|
-
"createdBy": {
|
97
|
-
"type": "string"
|
98
|
-
},
|
99
|
-
"role": {
|
100
|
-
"type": "string",
|
101
|
-
"enum": [
|
102
|
-
"bm",
|
103
|
-
"pdc",
|
104
|
-
"js",
|
105
|
-
"ux"
|
106
|
-
]
|
107
|
-
},
|
108
|
-
"hoursPerWeek": {
|
109
|
-
"type": "integer"
|
110
|
-
},
|
111
|
-
"start": {
|
112
|
-
"type": "string",
|
113
|
-
"format": "date-time"
|
114
|
-
},
|
115
|
-
"end": {
|
116
|
-
"type": [
|
117
|
-
"string",
|
118
|
-
"null"
|
119
|
-
],
|
120
|
-
"format": "date-time"
|
121
|
-
},
|
122
|
-
"uid": {
|
123
|
-
"type": "string"
|
124
|
-
},
|
125
|
-
"cohortId": {
|
126
|
-
"type": "integer"
|
127
|
-
},
|
128
|
-
"contract": {
|
129
|
-
"$ref": "#/definitions/Contract"
|
130
|
-
}
|
131
|
-
}
|
132
|
-
}
|
133
|
-
},
|
134
|
-
"type": "object",
|
135
|
-
"properties": {
|
136
|
-
"country": {
|
137
|
-
"$ref": "#/definitions/Country"
|
138
|
-
},
|
139
|
-
"contract": {
|
140
|
-
"$ref": "#/definitions/Contract"
|
141
|
-
},
|
142
|
-
"gig": {
|
143
|
-
"$ref": "#/definitions/Gig"
|
144
|
-
}
|
145
|
-
}
|
146
|
-
}
|