Skip to content

Commit 061aef1

Browse files
authored
Merge pull request #65 from scimmyjs/issue/63-typescript-type-fixes
Refine TypeScript types and address type resolution issues
2 parents 14e1eda + 968c6a6 commit 061aef1

24 files changed

+221
-57
lines changed

package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+17-5
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,24 @@
1212
"types": "./dist/scimmy.d.ts",
1313
"exports": {
1414
".": {
15-
"import": "./dist/scimmy.js",
16-
"require": "./dist/cjs/scimmy.cjs"
15+
"import": {
16+
"types": "./dist/scimmy.d.ts",
17+
"default": "./dist/scimmy.js"
18+
},
19+
"require": {
20+
"types": "./dist/scimmy.d.ts",
21+
"default": "./dist/cjs/scimmy.cjs"
22+
}
1723
},
1824
"./*": {
19-
"import": "./dist/lib/*.js",
20-
"require": "./dist/cjs/lib/*.js"
25+
"import": {
26+
"types": "./dist/scimmy.d.ts",
27+
"default": "./dist/lib/*.js"
28+
},
29+
"require": {
30+
"types": "./dist/scimmy.d.ts",
31+
"default": "./dist/cjs/lib/*.js"
32+
}
2133
}
2234
},
2335
"scripts": {
@@ -70,7 +82,7 @@
7082
"jsdoc": "^4.0.2",
7183
"minimist": "^1.2.8",
7284
"mocha": "^10.4.0",
73-
"ostensibly-typed": "^1.0.3",
85+
"ostensibly-typed": "^1.2.0",
7486
"rollup": "^4.25.0",
7587
"sinon": "^19.0.2",
7688
"typescript": "^5.4.5"

packager.js

+10-11
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,6 @@ export class Packager {
192192
const input = {[entry]: path.join(src, `${entry}.js`), ...chunks.reduce((chunks, chunk) => Object.assign(chunks, {[chunk]: path.join(src, `${chunk}.js`)}), {})};
193193
const manualChunks = chunks.reduce((chunks, chunk) => Object.assign(chunks, {[chunk]: [path.join(src, `${chunk}.js`)]}), {});
194194
const output = [];
195-
const config = {
196-
exports: "named", interop: "auto",
197-
minifyInternalExports: false,
198-
hoistTransitiveImports: false,
199-
manualChunks, generatedCode: {
200-
constBindings: true
201-
}
202-
};
203195

204196
// Prepare RollupJS bundle with supplied entry points
205197
const bundle = await rollup.rollup({
@@ -210,8 +202,15 @@ export class Packager {
210202
// Construct the bundles with specified chunks in specified formats and write to destination
211203
for (let format of ["esm", "cjs"]) {
212204
const {output: results} = await bundle.write({
213-
...config, format, dir: (format === "esm" ? dest : `${dest}/${format}`),
214-
entryFileNames: fileNameConfig[format], chunkFileNames: fileNameConfig[format]
205+
format, exports: "named", interop: "auto",
206+
dir: (format === "esm" ? dest : `${dest}/${format}`),
207+
entryFileNames: fileNameConfig[format],
208+
chunkFileNames: fileNameConfig[format],
209+
minifyInternalExports: false,
210+
hoistTransitiveImports: false,
211+
manualChunks, generatedCode: {
212+
constBindings: true
213+
}
215214
});
216215

217216
output.push(...results.map(file => (format === "esm" ? file.fileName : `${format}/${file.fileName}`)));
@@ -234,7 +233,7 @@ export class Packager {
234233

235234
// Prepare RollupJS with OstensiblyTyped plugin and supplied entry point
236235
const bundle = await rollup.rollup({
237-
external, input: path.join(src, `${entry}.js`),
236+
external, input: path.join(src, `${entry}.js`),
238237
plugins: [generateDeclarations({moduleName: entry, defaultExport: "SCIMMY"})],
239238
onwarn: (warning, warn) => (warning.code !== "CIRCULAR_DEPENDENCY" ? warn(warning) : false)
240239
});

src/lib/messages/bulkrequest.js

+16-5
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,27 @@ export class BulkRequest {
3434
#dispatched = false;
3535

3636
/**
37-
* Instantiate a new SCIM BulkResponse message from the supplied BulkRequest
37+
* BulkRequest operation details
38+
* @typedef {Object} SCIMMY.Messages.BulkRequest~BulkOpOperation
39+
* @property {SCIMMY.Messages.BulkRequest~ValidBulkMethods} method - the HTTP method used for the requested operation
40+
* @property {String} [bulkId] - the transient identifier of a newly created resource, unique within a bulk request and created by the client
41+
* @property {String} [version] - resource version after operation has been applied
42+
* @property {String} [path] - the resource's relative path to the SCIM service provider's root
43+
* @property {Object} [data] - the resource data as it would appear for the corresponding single SCIM HTTP request
44+
* @inner
45+
*/
46+
47+
/**
48+
* Instantiate a new SCIM BulkRequest message from the supplied operations
3849
* @param {Object} request - contents of the BulkRequest operation being performed
39-
* @param {Object[]} request.Operations - list of SCIM-compliant bulk operations to apply
50+
* @param {SCIMMY.Messages.BulkRequest~BulkOpOperation[]} request.Operations - list of SCIM-compliant bulk operations to apply
4051
* @param {Number} [request.failOnErrors] - number of error results to encounter before aborting any following operations
4152
* @param {Number} [maxOperations] - maximum number of operations supported in the request, as specified by the service provider
42-
* @property {Object[]} Operations - list of operations in this BulkRequest instance
53+
* @property {SCIMMY.Messages.BulkRequest~BulkOpOperation[]} Operations - list of operations in this BulkRequest instance
4354
* @property {Number} [failOnErrors] - number of error results a service provider should tolerate before aborting any following operations
4455
*/
4556
constructor(request, maxOperations = 0) {
46-
let {schemas = [], Operations: operations = [], failOnErrors = 0} = request ?? {};
57+
const {schemas = [], Operations: operations = [], failOnErrors = 0} = request ?? {};
4758

4859
// Make sure specified schema is valid
4960
if (schemas.length !== 1 || !schemas.includes(BulkRequest.#id))
@@ -69,7 +80,7 @@ export class BulkRequest {
6980
}
7081

7182
/**
72-
* Apply the operations specified by the supplied BulkRequest
83+
* Apply the operations specified by the supplied BulkRequest and return a new BulkResponse message
7384
* @param {typeof SCIMMY.Types.Resource[]} [resourceTypes] - resource type classes to be used while processing bulk operations, defaults to declared resources
7485
* @param {*} [ctx] - any additional context information to pass to the ingress, egress, and degress handlers
7586
* @returns {SCIMMY.Messages.BulkResponse} a new BulkResponse Message instance with results of the requested operations

src/lib/messages/bulkresponse.js

+35-5
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,45 @@ export class BulkResponse {
1414
*/
1515
static #id = "urn:ietf:params:scim:api:messages:2.0:BulkResponse";
1616

17+
/**
18+
* BulkResponse operation response status codes
19+
* @enum {200|201|204|307|308|400|401|403|404|409|412|500|501} SCIMMY.Messages.BulkResponse~ResponseStatusCodes
20+
* @inner
21+
*/
22+
23+
/**
24+
* BulkResponse operation details for a given BulkRequest operation
25+
* @typedef {Object} SCIMMY.Messages.BulkResponse~BulkOpResponse
26+
* @property {String} [location] - canonical URI for the target resource of the operation
27+
* @property {SCIMMY.Messages.BulkRequest~ValidBulkMethods} method - the HTTP method used for the requested operation
28+
* @property {String} [bulkId] - the transient identifier of a newly created resource, unique within a bulk request and created by the client
29+
* @property {String} [version] - resource version after operation has been applied
30+
* @property {SCIMMY.Messages.BulkResponse~ResponseStatusCodes} status - the HTTP response status code for the requested operation
31+
* @property {Object} [response] - the HTTP response body for the specified request operation
32+
* @inner
33+
*/
34+
35+
/**
36+
* Instantiate a new outbound SCIM BulkResponse message from the results of performed operations
37+
* @overload
38+
* @param {SCIMMY.Messages.BulkResponse~BulkOpResponse[]} operations - results of performed operations
39+
*/
40+
/**
41+
* Instantiate a new inbound SCIM BulkResponse message instance from the received response
42+
* @overload
43+
* @param {Object} request - contents of the received BulkResponse message
44+
* @param {SCIMMY.Messages.BulkResponse~BulkOpResponse[]} request.Operations - list of SCIM-compliant bulk operation results
45+
*/
1746
/**
1847
* Instantiate a new SCIM BulkResponse message from the supplied Operations
19-
* @param {Object|Object[]} request - contents of the BulkResponse if object, or results of performed operations if array
20-
* @param {Object[]} [request.Operations] - list of applied SCIM-compliant bulk operation results, if request is an object
21-
* @property {Object[]} Operations - list of BulkResponse operation results
48+
* @param {SCIMMY.Messages.BulkResponse~BulkOpResponse[]} request - results of performed operations if array
49+
* @param {Object} request - contents of the received BulkResponse message if object
50+
* @param {SCIMMY.Messages.BulkResponse~BulkOpResponse[]} request.Operations - list of SCIM-compliant bulk operation results
51+
* @property {SCIMMY.Messages.BulkResponse~BulkOpResponse[]} Operations - list of BulkResponse operation results
2252
*/
2353
constructor(request = []) {
24-
let outbound = Array.isArray(request),
25-
operations = (outbound ? request : request?.Operations ?? []);
54+
const outbound = Array.isArray(request);
55+
const operations = (outbound ? request : request?.Operations ?? []);
2656

2757
// Verify the BulkResponse contents are valid
2858
if (!outbound && Array.isArray(request?.schemas) && (!request.schemas.includes(BulkResponse.#id) || request.schemas.length > 1))

src/lib/messages/error.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ export class ErrorResponse extends Error {
3636
static #id = "urn:ietf:params:scim:api:messages:2.0:Error";
3737

3838
/**
39+
* Details of the underlying cause of the error response
3940
* @typedef {Object} SCIMMY.Messages.ErrorResponse~CauseDetails
4041
* @property {SCIMMY.Messages.ErrorResponse~ValidStatusCodes} [status=500] - HTTP status code to be sent with the error
4142
* @property {SCIMMY.Messages.ErrorResponse~ValidScimTypes} [scimType] - the SCIM detail error keyword as per [RFC7644§3.12]{@link https://datatracker.ietf.org/doc/html/rfc7644#section-3.12}
4243
* @property {String} [detail] - a human-readable description of what caused the error to occur
43-
* @internal
4444
* @inner
4545
*/
4646

src/lib/messages/listresponse.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,19 @@ export class ListResponse {
1212
*/
1313
static #id = "urn:ietf:params:scim:api:messages:2.0:ListResponse";
1414

15+
/**
16+
* ListResponse sort and pagination constraints
17+
* @typedef {Object} SCIMMY.Messages.ListResponse~ListConstraints
18+
* @property {String} [sortBy] - the attribute to sort results by, if any
19+
* @property {String} [sortOrder="ascending"] - the direction to sort results in, if sortBy is specified
20+
* @property {Number} [startIndex=1] - offset index that items start from
21+
* @property {Number} [count=20] - maximum number of items returned in this list response
22+
*/
23+
1524
/**
1625
* Instantiate a new SCIM List Response Message with relevant details
1726
* @param {Object|SCIMMY.Types.Schema[]} request - contents of the ListResponse message, or items to include in the list response
18-
* @param {Object} [params] - parameters for the list response (i.e. sort details, start index, and items per page)
19-
* @param {String} [params.sortBy] - the attribute to sort results by, if any
20-
* @param {String} [params.sortOrder="ascending"] - the direction to sort results in, if sortBy is specified
21-
* @param {Number} [params.startIndex=1] - offset index that items start from
27+
* @param {SCIMMY.Messages.ListResponse~ListConstraints} [params] - parameters for the list response (i.e. sort details, start index, and items per page)
2228
* @param {Number} [params.count=20] - alias property for itemsPerPage, used only if itemsPerPage is unset
2329
* @param {Number} [params.itemsPerPage=20] - maximum number of items returned in this list response
2430
* @property {Array<Object|SCIMMY.Types.Schema>} Resources - resources included in the list response

src/lib/resources/group.js

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ export class Group extends Types.Resource {
3434
return Schemas.Group;
3535
}
3636

37+
/** @implements {SCIMMY.Types.Resource.extend<typeof SCIMMY.Resources.Group>} */
38+
static extend(...args) {
39+
return super.extend(...args);
40+
}
41+
3742
/** @private */
3843
static #ingress = () => {
3944
throw new Types.Error(501, null, "Method 'ingress' not implemented by resource 'Group'");

src/lib/resources/user.js

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ export class User extends Types.Resource {
3434
return Schemas.User;
3535
}
3636

37+
/** @implements {SCIMMY.Types.Resource.extend<typeof SCIMMY.Resources.User>} */
38+
static extend(...args) {
39+
return super.extend(...args);
40+
}
41+
3742
/** @private */
3843
static #ingress = () => {
3944
throw new Types.Error(501, null, "Method 'ingress' not implemented by resource 'User'");

src/lib/schemas/enterpriseuser.js

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ import Types from "../types.js";
88
* * Can be used directly, but is typically used to extend the `SCIMMY.Schemas.User` schema definition.
99
*/
1010
export class EnterpriseUser extends Types.Schema {
11+
/** @type {"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"} */
12+
static get id() {
13+
return EnterpriseUser.#definition.id;
14+
}
15+
1116
/** @implements {SCIMMY.Types.Schema.definition} */
1217
static get definition() {
1318
return EnterpriseUser.#definition;

src/lib/schemas/group.js

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import Types from "../types.js";
77
* * Ensures a Group instance conforms to the Group schema set out in [RFC7643§4.2](https://datatracker.ietf.org/doc/html/rfc7643#section-4.2).
88
*/
99
export class Group extends Types.Schema {
10+
/** @type {"urn:ietf:params:scim:schemas:core:2.0:Group"} */
11+
static get id() {
12+
return Group.#definition.id;
13+
}
14+
1015
/** @implements {SCIMMY.Types.Schema.definition} */
1116
static get definition() {
1217
return Group.#definition;

src/lib/schemas/resourcetype.js

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import Types from "../types.js";
77
* * Ensures a ResourceType instance conforms to the ResourceType schema set out in [RFC7643§6](https://datatracker.ietf.org/doc/html/rfc7643#section-6).
88
*/
99
export class ResourceType extends Types.Schema {
10+
/** @type {"urn:ietf:params:scim:schemas:core:2.0:ResourceType"} */
11+
static get id() {
12+
return ResourceType.#definition.id;
13+
}
14+
1015
/** @implements {SCIMMY.Types.Schema.definition} */
1116
static get definition() {
1217
return ResourceType.#definition;

src/lib/schemas/spconfig.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@ import Types from "../types.js";
77
* * Ensures a ServiceProviderConfig instance conforms to the Service Provider Configuration schema set out in [RFC7643§5](https://datatracker.ietf.org/doc/html/rfc7643#section-5).
88
*/
99
export class ServiceProviderConfig extends Types.Schema {
10+
/** @type {"urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"} */
11+
static get id() {
12+
return ServiceProviderConfig.#definition.id;
13+
}
14+
1015
/** @implements {SCIMMY.Types.Schema.definition} */
1116
static get definition() {
1217
return ServiceProviderConfig.#definition;
1318
}
1419

1520
/** @private */
1621
static #definition = new Types.SchemaDefinition(
17-
"ServiceProviderConfig", "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",
18-
"Schema for representing the service provider's configuration", [
22+
"ServiceProviderConfig", "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig", "Schema for representing the service provider's configuration", [
1923
new Types.Attribute("reference", "documentationUri", {mutable: false, referenceTypes: ["external"], description: "An HTTP-addressable URL pointing to the service provider's human-consumable help documentation."}),
2024
new Types.Attribute("complex", "patch", {required: true, mutable: false, uniqueness: false, description: "A complex type that specifies PATCH configuration options."}, [
2125
new Types.Attribute("boolean", "supported", {required: true, mutable: false, description: "A Boolean value specifying whether or not the operation is supported."})

src/lib/schemas/user.js

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)