lumen-framework 3.1.1 → 4.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 +75 -109
- package/bin/lumen +23 -41
- package/dist/cli.cjs +856 -479
- package/dist/cli.cjs.map +4 -4
- package/dist/index.js +3273 -1719
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +3251 -1697
- package/dist/index.mjs.map +4 -4
- package/dist/testing.js +280 -0
- package/dist/testing.js.map +7 -0
- package/dist/testing.mjs +252 -0
- package/dist/testing.mjs.map +7 -0
- package/dist/types/errors/links-only-error.d.ts +13 -0
- package/dist/types/errors/reserved-field-name-error.d.ts +13 -0
- package/dist/types/errors/unknown-attribute-error.d.ts +13 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/interfaces.d.ts +1 -1
- package/dist/types/packages/application/index.d.ts +38 -45
- package/dist/types/packages/application/initialize.d.ts +3 -5
- package/dist/types/packages/application/interfaces.d.ts +13 -5
- package/dist/types/packages/application/utils/create-controller.d.ts +14 -4
- package/dist/types/packages/application/utils/create-serializer.d.ts +2 -2
- package/dist/types/packages/application/utils/normalize-port.d.ts +1 -3
- package/dist/types/packages/application/utils/resolve-visibility.d.ts +15 -0
- package/dist/types/packages/application/utils/restrict-open-namespaces.d.ts +19 -0
- package/dist/types/packages/application/utils/validate-attributes.d.ts +17 -0
- package/dist/types/packages/application/utils/validate-links-only.d.ts +19 -0
- package/dist/types/packages/application/utils/validate-namespaced-serializers.d.ts +3 -3
- package/dist/types/packages/application/utils/validate-reserved-names.d.ts +12 -0
- package/dist/types/packages/application/utils/warn-query-param-names.d.ts +10 -0
- package/dist/types/packages/cli/commands/dbcreate.d.ts +1 -1
- package/dist/types/packages/cli/commands/dbdrop.d.ts +1 -1
- package/dist/types/packages/cli/commands/destroy.d.ts +3 -2
- package/dist/types/packages/cli/commands/generate.d.ts +5 -5
- package/dist/types/packages/cli/commands/index.d.ts +0 -1
- package/dist/types/packages/cli/generator/index.d.ts +6 -6
- package/dist/types/packages/cli/generator/interfaces.d.ts +3 -3
- package/dist/types/packages/cli/generator/utils/create-generator.d.ts +2 -2
- package/dist/types/packages/cli/generator/utils/generate-type.d.ts +9 -9
- package/dist/types/packages/cli/generator/utils/migration-conflict.d.ts +4 -4
- package/dist/types/packages/cli/templates/pnpm-workspace.d.ts +15 -0
- package/dist/types/packages/cli/utils/create-spinner.d.ts +14 -0
- package/dist/types/packages/cli/utils/print-statements.d.ts +12 -0
- package/dist/types/packages/cli/utils/server-database.d.ts +27 -0
- package/dist/types/packages/compiler/interfaces.d.ts +1 -1
- package/dist/types/packages/config/interfaces.d.ts +10 -4
- package/dist/types/packages/controller/constants.d.ts +7 -2
- package/dist/types/packages/controller/errors/related-record-not-found-error.d.ts +4 -4
- package/dist/types/packages/controller/index.d.ts +364 -473
- package/dist/types/packages/controller/interfaces.d.ts +21 -6
- package/dist/types/packages/controller/utils/find-many.d.ts +2 -5
- package/dist/types/packages/controller/utils/find-one.d.ts +2 -5
- package/dist/types/packages/controller/utils/params-to-query.d.ts +8 -10
- package/dist/types/packages/controller/utils/resolve-relationships.d.ts +1 -3
- package/dist/types/packages/controller/utils/validate-relationships.d.ts +5 -3
- package/dist/types/packages/controller/visibility/errors.d.ts +21 -0
- package/dist/types/packages/controller/visibility/index.d.ts +51 -0
- package/dist/types/packages/database/attribute/index.d.ts +4 -6
- package/dist/types/packages/database/attribute/interfaces.d.ts +1 -1
- package/dist/types/packages/database/attribute/utils/create-attribute.d.ts +3 -5
- package/dist/types/packages/database/attribute/utils/create-getter.d.ts +2 -2
- package/dist/types/packages/database/attribute/utils/create-setter.d.ts +3 -5
- package/dist/types/packages/database/constants.d.ts +1 -0
- package/dist/types/packages/database/errors/index.d.ts +1 -0
- package/dist/types/packages/database/errors/invalid-driver-error.d.ts +1 -3
- package/dist/types/packages/database/errors/migrations-pending-error.d.ts +1 -3
- package/dist/types/packages/database/errors/model-missing-error.d.ts +1 -3
- package/dist/types/packages/database/errors/relationship-config-error.d.ts +10 -0
- package/dist/types/packages/database/errors/unique-constraint-error.d.ts +1 -1
- package/dist/types/packages/database/index.d.ts +9 -6
- package/dist/types/packages/database/initialize.d.ts +3 -5
- package/dist/types/packages/database/interfaces.d.ts +115 -25
- package/dist/types/packages/database/migration/index.d.ts +5 -7
- package/dist/types/packages/database/migration/interfaces.d.ts +2 -4
- package/dist/types/packages/database/migration/utils/generate-timestamp.d.ts +9 -1
- package/dist/types/packages/database/model/index.d.ts +348 -759
- package/dist/types/packages/database/model/initialize-class.d.ts +7 -1
- package/dist/types/packages/database/model/interfaces.d.ts +30 -12
- package/dist/types/packages/database/model/utils/attribute.d.ts +14 -0
- package/dist/types/packages/database/model/utils/get-columns.d.ts +1 -3
- package/dist/types/packages/database/model/utils/persistence.d.ts +5 -14
- package/dist/types/packages/database/model/utils/process-write-error.d.ts +2 -2
- package/dist/types/packages/database/model/utils/run-hooks.d.ts +7 -3
- package/dist/types/packages/database/model/utils/validate.d.ts +4 -1
- package/dist/types/packages/database/query/errors/record-not-found-error.d.ts +1 -1
- package/dist/types/packages/database/query/index.d.ts +179 -3
- package/dist/types/packages/database/query/runner/index.d.ts +1 -3
- package/dist/types/packages/database/query/runner/utils/build-results.d.ts +3 -4
- package/dist/types/packages/database/query/utils/format-select.d.ts +1 -3
- package/dist/types/packages/database/relationship/index.d.ts +7 -6
- package/dist/types/packages/database/relationship/interfaces.d.ts +16 -3
- package/dist/types/packages/database/relationship/utils/getters.d.ts +7 -13
- package/dist/types/packages/database/relationship/utils/inverse-setters.d.ts +5 -9
- package/dist/types/packages/database/relationship/utils/setters.d.ts +7 -13
- package/dist/types/packages/database/relationship/utils/unassociate.d.ts +1 -3
- package/dist/types/packages/database/relationship/utils/update-relationship.d.ts +6 -2
- package/dist/types/packages/database/transaction/index.d.ts +9 -10
- package/dist/types/packages/database/transaction/interfaces.d.ts +7 -1
- package/dist/types/packages/database/utils/connect.d.ts +16 -3
- package/dist/types/packages/database/utils/create-migrations.d.ts +1 -3
- package/dist/types/packages/database/utils/normalize-model-name.d.ts +1 -3
- package/dist/types/packages/database/utils/pending-migrations.d.ts +1 -3
- package/dist/types/packages/database/utils/primary-key-type.d.ts +10 -0
- package/dist/types/packages/database/utils/type-for-column.d.ts +3 -5
- package/dist/types/packages/database/utils/validate-relationships.d.ts +13 -0
- package/dist/types/packages/database/validation/errors/validation-error.d.ts +4 -4
- package/dist/types/packages/database/validation/index.d.ts +3 -5
- package/dist/types/packages/database/validation/interfaces.d.ts +1 -1
- package/dist/types/packages/freezeable/map/index.d.ts +1 -3
- package/dist/types/packages/freezeable/set/index.d.ts +1 -3
- package/dist/types/packages/freezeable/utils/freeze.d.ts +5 -15
- package/dist/types/packages/freezeable/utils/is-frozen.d.ts +1 -3
- package/dist/types/packages/fs/index.d.ts +7 -7
- package/dist/types/packages/fs/interfaces.d.ts +4 -4
- package/dist/types/packages/fs/utils/parse-path.d.ts +2 -2
- package/dist/types/packages/fs/watcher/interfaces.d.ts +1 -1
- package/dist/types/packages/jsonapi/errors/invalid-content-type-error.d.ts +3 -5
- package/dist/types/packages/jsonapi/errors/not-acceptable-error.d.ts +2 -4
- package/dist/types/packages/jsonapi/errors/unsupported-media-type-error.d.ts +2 -4
- package/dist/types/packages/jsonapi/index.d.ts +1 -1
- package/dist/types/packages/jsonapi/interfaces.d.ts +47 -36
- package/dist/types/packages/jsonapi/utils/has-media-type-params.d.ts +1 -1
- package/dist/types/packages/jsonapi/utils/is-jsonapi.d.ts +1 -1
- package/dist/types/packages/jsonapi/utils/media-type.d.ts +2 -2
- package/dist/types/packages/loader/builder/index.d.ts +3 -3
- package/dist/types/packages/loader/builder/interfaces.d.ts +7 -7
- package/dist/types/packages/loader/builder/utils/create-children-builder.d.ts +2 -2
- package/dist/types/packages/loader/builder/utils/create-parent-builder.d.ts +9 -2
- package/dist/types/packages/loader/builder/utils/sort-by-namespace.d.ts +2 -2
- package/dist/types/packages/loader/index.d.ts +1 -1
- package/dist/types/packages/loader/interfaces.d.ts +2 -2
- package/dist/types/packages/loader/resolver/index.d.ts +2 -2
- package/dist/types/packages/loader/resolver/utils/closest-ancestor.d.ts +2 -2
- package/dist/types/packages/loader/resolver/utils/closest-child.d.ts +2 -2
- package/dist/types/packages/logger/constants.d.ts +3 -3
- package/dist/types/packages/logger/errors/invalid-config-error.d.ts +5 -0
- package/dist/types/packages/logger/index.d.ts +65 -142
- package/dist/types/packages/logger/interfaces.d.ts +52 -10
- package/dist/types/packages/logger/request-logger/index.d.ts +3 -5
- package/dist/types/packages/logger/request-logger/interfaces.d.ts +5 -5
- package/dist/types/packages/logger/request-logger/templates.d.ts +5 -9
- package/dist/types/packages/logger/request-logger/utils/filter-params.d.ts +6 -1
- package/dist/types/packages/logger/request-logger/utils/log-json.d.ts +2 -4
- package/dist/types/packages/logger/request-logger/utils/log-text.d.ts +1 -3
- package/dist/types/packages/logger/request-logger/utils/params-for.d.ts +9 -0
- package/dist/types/packages/logger/utils/error-name.d.ts +7 -0
- package/dist/types/packages/logger/utils/line.d.ts +1 -3
- package/dist/types/packages/logger/writer/constants.d.ts +0 -1
- package/dist/types/packages/logger/writer/index.d.ts +6 -6
- package/dist/types/packages/logger/writer/interfaces.d.ts +2 -2
- package/dist/types/packages/logger/writer/utils/format-message.d.ts +2 -2
- package/dist/types/packages/lumenify/index.d.ts +20 -5
- package/dist/types/packages/lumenify/utils/create-response-proxy.d.ts +1 -1
- package/dist/types/packages/pm/cluster/index.d.ts +56 -7
- package/dist/types/packages/pm/cluster/interfaces.d.ts +2 -1
- package/dist/types/packages/pm/index.d.ts +2 -2
- package/dist/types/packages/router/definitions/context/index.d.ts +5 -7
- package/dist/types/packages/router/definitions/context/utils/create-definition-group.d.ts +3 -5
- package/dist/types/packages/router/definitions/context/utils/create-definition.d.ts +11 -6
- package/dist/types/packages/router/definitions/context/utils/normalize-resource-args.d.ts +4 -5
- package/dist/types/packages/router/definitions/index.d.ts +5 -9
- package/dist/types/packages/router/definitions/interfaces.d.ts +4 -4
- package/dist/types/packages/router/index.d.ts +23 -11
- package/dist/types/packages/router/interfaces.d.ts +4 -4
- package/dist/types/packages/router/namespace/index.d.ts +7 -9
- package/dist/types/packages/router/namespace/interfaces.d.ts +3 -3
- package/dist/types/packages/router/namespace/utils/normalize-name.d.ts +1 -3
- package/dist/types/packages/router/namespace/utils/normalize-path.d.ts +1 -3
- package/dist/types/packages/router/resource/index.d.ts +7 -8
- package/dist/types/packages/router/resource/interfaces.d.ts +12 -4
- package/dist/types/packages/router/resource/utils/normalize-only.d.ts +3 -5
- package/dist/types/packages/router/route/action/enhancers/resource.d.ts +1 -3
- package/dist/types/packages/router/route/action/enhancers/track-perf.d.ts +1 -3
- package/dist/types/packages/router/route/action/index.d.ts +7 -2
- package/dist/types/packages/router/route/action/interfaces.d.ts +4 -0
- package/dist/types/packages/router/route/action/utils/create-page-links.d.ts +21 -5
- package/dist/types/packages/router/route/action/utils/get-action-name.d.ts +1 -3
- package/dist/types/packages/router/route/action/utils/get-controller-name.d.ts +1 -3
- package/dist/types/packages/router/route/index.d.ts +13 -9
- package/dist/types/packages/router/route/interfaces.d.ts +7 -5
- package/dist/types/packages/router/route/params/errors/client-generated-id-error.d.ts +4 -4
- package/dist/types/packages/router/route/params/errors/forbidden-parameter-error.d.ts +4 -4
- package/dist/types/packages/router/route/params/errors/index.d.ts +1 -0
- package/dist/types/packages/router/route/params/errors/invalid-parameter-error.d.ts +4 -6
- package/dist/types/packages/router/route/params/errors/parameter-not-nullable-error.d.ts +4 -6
- package/dist/types/packages/router/route/params/errors/parameter-range-error.d.ts +9 -0
- package/dist/types/packages/router/route/params/errors/parameter-required-error.d.ts +4 -6
- package/dist/types/packages/router/route/params/errors/parameter-type-error.d.ts +4 -6
- package/dist/types/packages/router/route/params/errors/parameter-value-error.d.ts +4 -6
- package/dist/types/packages/router/route/params/errors/resource-mismatch-error.d.ts +4 -6
- package/dist/types/packages/router/route/params/index.d.ts +5 -9
- package/dist/types/packages/router/route/params/interfaces.d.ts +12 -8
- package/dist/types/packages/router/route/params/parameter/forbidden-parameter.d.ts +1 -1
- package/dist/types/packages/router/route/params/parameter/ignored-parameter.d.ts +14 -0
- package/dist/types/packages/router/route/params/parameter/index.d.ts +21 -5
- package/dist/types/packages/router/route/params/parameter/interfaces.d.ts +2 -2
- package/dist/types/packages/router/route/params/parameter/utils/validate-range.d.ts +3 -0
- package/dist/types/packages/router/route/params/parameter/utils/validate-value.d.ts +1 -3
- package/dist/types/packages/router/route/params/parameter-group/index.d.ts +3 -5
- package/dist/types/packages/router/route/params/parameter-group/utils/missing-params.d.ts +8 -0
- package/dist/types/packages/router/route/params/utils/get-data-params.d.ts +5 -1
- package/dist/types/packages/router/route/params/utils/get-default-collection-params.d.ts +1 -3
- package/dist/types/packages/router/route/params/utils/get-default-member-params.d.ts +5 -2
- package/dist/types/packages/router/route/params/utils/get-query-params.d.ts +3 -9
- package/dist/types/packages/router/route/params/utils/get-url-params.d.ts +1 -3
- package/dist/types/packages/router/route/params/utils/parse-column-value.d.ts +16 -0
- package/dist/types/packages/router/route/params/utils/validate-client-id.d.ts +1 -1
- package/dist/types/packages/router/route/params/utils/validate-resource-id.d.ts +1 -3
- package/dist/types/packages/router/route/params/utils/validate-type.d.ts +3 -5
- package/dist/types/packages/router/route/utils/get-dynamic-segments.d.ts +1 -3
- package/dist/types/packages/router/route/utils/get-static-path.d.ts +6 -2
- package/dist/types/packages/router/utils/create-replacer.d.ts +10 -2
- package/dist/types/packages/serializer/index.d.ts +243 -434
- package/dist/types/packages/serializer/interfaces.d.ts +19 -1
- package/dist/types/packages/serializer/utils/include-tree.d.ts +12 -3
- package/dist/types/packages/serializer/utils/load-linkage.d.ts +9 -3
- package/dist/types/packages/server/errors/error-list.d.ts +25 -0
- package/dist/types/packages/server/errors/method-not-allowed-error.d.ts +11 -0
- package/dist/types/packages/server/index.d.ts +9 -9
- package/dist/types/packages/server/interfaces.d.ts +59 -7
- package/dist/types/packages/server/request/constants.d.ts +2 -2
- package/dist/types/packages/server/request/index.d.ts +3 -5
- package/dist/types/packages/server/request/interfaces.d.ts +72 -8
- package/dist/types/packages/server/request/parser/errors/malformed-request-error.d.ts +3 -5
- package/dist/types/packages/server/request/parser/index.d.ts +6 -1
- package/dist/types/packages/server/request/parser/utils/format.d.ts +13 -11
- package/dist/types/packages/server/request/parser/utils/normalize-document.d.ts +13 -0
- package/dist/types/packages/server/request/parser/utils/parse-nested-object.d.ts +1 -3
- package/dist/types/packages/server/request/parser/utils/parse-read.d.ts +2 -4
- package/dist/types/packages/server/request/parser/utils/parse-write.d.ts +17 -1
- package/dist/types/packages/server/request/utils/get-domain.d.ts +1 -3
- package/dist/types/packages/server/responder/index.d.ts +1 -3
- package/dist/types/packages/server/responder/utils/content-type-for.d.ts +8 -0
- package/dist/types/packages/server/responder/utils/data-for.d.ts +3 -5
- package/dist/types/packages/server/responder/utils/normalize.d.ts +2 -3
- package/dist/types/packages/server/response/index.d.ts +3 -5
- package/dist/types/packages/server/response/interfaces.d.ts +14 -3
- package/dist/types/packages/server/utils/client-ip-for.d.ts +10 -0
- package/dist/types/packages/server/utils/create-server-error.d.ts +11 -3
- package/dist/types/packages/server/utils/request-id-for.d.ts +9 -0
- package/dist/types/packages/server/utils/set-cors-headers.d.ts +2 -2
- package/dist/types/packages/server/utils/source-for.d.ts +19 -3
- package/dist/types/packages/server/utils/status-for-error.d.ts +6 -0
- package/dist/types/packages/server/utils/validate-accept.d.ts +1 -1
- package/dist/types/packages/server/utils/validate-content-type.d.ts +8 -3
- package/dist/types/packages/testing/audit-visibility.d.ts +189 -0
- package/dist/types/packages/testing/index.d.ts +4 -0
- package/dist/types/packages/testing/start-app.d.ts +52 -0
- package/dist/types/packages/testing/utils/identifiers-in.d.ts +14 -0
- package/dist/types/testing.d.ts +9 -0
- package/dist/types/utils/chalk.d.ts +16 -0
- package/dist/types/utils/pick.d.ts +2 -2
- package/package.json +54 -26
- package/dist/types/packages/cli/commands/test.d.ts +0 -4
- package/dist/types/packages/logger/utils/sql.d.ts +0 -4
- package/dist/types/packages/router/route/params/parameter-group/utils/has-required-params.d.ts +0 -5
- package/dist/types/utils/create-query-string.d.ts +0 -6
- package/dist/types/utils/has-own-property.d.ts +0 -1
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ServerErrorSource } from '../interfaces';
|
|
2
2
|
/**
|
|
3
3
|
* Map an internal parameter path to a JSON:API error `source`. Paths under
|
|
4
4
|
* `data` are request document members and become a JSON Pointer
|
|
5
5
|
* (`data.attributes.isPublic` -> `/data/attributes/is-public`); anything else
|
|
6
6
|
* is a query parameter (`page.size` -> `page[size]`).
|
|
7
7
|
*
|
|
8
|
-
* @
|
|
8
|
+
* @internal
|
|
9
9
|
*/
|
|
10
|
-
export default function sourceFor(path: string):
|
|
10
|
+
export default function sourceFor(path: string): ServerErrorSource;
|
|
11
|
+
/**
|
|
12
|
+
* A parameter path as the client writes it, for error messages: request
|
|
13
|
+
* document members dasherized and dotted (`data.attributes.is-public`), query
|
|
14
|
+
* parameters in brackets (`filter[created-at]`, `page[size]`).
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare function nameFor(path: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* A member name or relationship path as it appears in documents, keeping a
|
|
21
|
+
* `sort` value's leading `-` (`-createdAt` -> `-created-at`,
|
|
22
|
+
* `comments.user` stays dotted). Anything but a string is returned as is.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export declare function memberPathFor(value: unknown): unknown;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* JSON:API 1.0: respond 415 if the Content-Type is the JSON:API media type
|
|
3
3
|
* with any media type parameters. A missing or different Content-Type is
|
|
4
|
-
* also answered with 415, since that is the only type
|
|
4
|
+
* also answered with 415, since that is the only type a resource accepts.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* A plain route (`json`) takes any JSON body, so `application/json` (with
|
|
7
|
+
* any parameters, such as `charset`) is accepted there too.
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
7
10
|
*/
|
|
8
|
-
export default function validateContentType(contentType?: string
|
|
11
|
+
export default function validateContentType(contentType?: string, { json }?: {
|
|
12
|
+
json?: boolean;
|
|
13
|
+
}): true;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import type Application from '../application';
|
|
2
|
+
/**
|
|
3
|
+
* Which records of one type a request may see, for {@link auditVisibility}:
|
|
4
|
+
* every one (`true`), the ids listed, or the ids a function accepts.
|
|
5
|
+
*/
|
|
6
|
+
export type VisibleRecords = true | ReadonlyArray<string | number> | ((id: string) => boolean);
|
|
7
|
+
/** The options of {@link auditVisibility}. */
|
|
8
|
+
export type AuditVisibilityOptions = {
|
|
9
|
+
/**
|
|
10
|
+
* The namespace to audit: `''` (the default) for the root, `'admin'` for
|
|
11
|
+
* `/admin`. Nested namespaces are audited on their own.
|
|
12
|
+
*/
|
|
13
|
+
namespace?: string;
|
|
14
|
+
/**
|
|
15
|
+
* What the request may see, keyed by type. Written by hand, independently
|
|
16
|
+
* of the app's visibility rules: it is what they are checked against. A
|
|
17
|
+
* type left out may not appear at all.
|
|
18
|
+
*/
|
|
19
|
+
visible: Record<string, VisibleRecords>;
|
|
20
|
+
/**
|
|
21
|
+
* Headers sent with every request, such as the `Authorization` of the user
|
|
22
|
+
* the audit is for.
|
|
23
|
+
*/
|
|
24
|
+
headers?: Record<string, string>;
|
|
25
|
+
/**
|
|
26
|
+
* The ids to request each type's routes with (`GET /posts/:id`,
|
|
27
|
+
* `/posts/:id/comments`, …), keyed by type: visible and hidden ones
|
|
28
|
+
* alike. A type left out is requested with every id in the database, so
|
|
29
|
+
* keep the database small or list the ids.
|
|
30
|
+
*/
|
|
31
|
+
ids?: Record<string, ReadonlyArray<string | number>>;
|
|
32
|
+
/**
|
|
33
|
+
* Query parameters a read requires, keyed by the type it serves: they are
|
|
34
|
+
* sent with that type's list, its records by id, and every related
|
|
35
|
+
* endpoint that serves it (`/posts/:id/comments` serves `comments`, and
|
|
36
|
+
* takes the parameters of the comments' controller). Relationship
|
|
37
|
+
* endpoints take none.
|
|
38
|
+
*
|
|
39
|
+
* ```javascript
|
|
40
|
+
* query: { comments: { fromDate: '2026-01-01' } }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
query?: Record<string, Record<string, string>>;
|
|
44
|
+
/**
|
|
45
|
+
* Where the application is served, when not by `app` itself: a server
|
|
46
|
+
* started as a separate process (`lumen serve`), such as
|
|
47
|
+
* `'http://localhost:4000'`. `app` still provides the routes, the
|
|
48
|
+
* include paths and the ids, so it must be booted in the test, but need
|
|
49
|
+
* not listen.
|
|
50
|
+
*/
|
|
51
|
+
origin?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Called with each document a read answers with, for checks beyond which
|
|
54
|
+
* records appear, such as the fields a request may see of each. Return a
|
|
55
|
+
* message, or several, for each problem found: each is reported as a
|
|
56
|
+
* violation of that request. May be async.
|
|
57
|
+
*
|
|
58
|
+
* ```javascript
|
|
59
|
+
* onDocument({ document }) {
|
|
60
|
+
* return document.included
|
|
61
|
+
* ?.filter(({ type, attributes }) => type === 'users' && attributes.email)
|
|
62
|
+
* .map(({ id }) => `users ${id} shows its email`);
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
onDocument?: (response: AuditedDocument) => DocumentCheckResult | Promise<DocumentCheckResult>;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* The read a request was made to, as the route defines it: so a check need
|
|
70
|
+
* not parse the URL to know which record it is about.
|
|
71
|
+
*/
|
|
72
|
+
export type AuditedRoute = {
|
|
73
|
+
/** The action, as hooks see it. */
|
|
74
|
+
action: 'index' | 'show' | 'showRelationship' | 'showRelated';
|
|
75
|
+
/**
|
|
76
|
+
* The route's resource type: for a relationship or related endpoint, the
|
|
77
|
+
* owner's (`posts` for `/posts/3/comments`).
|
|
78
|
+
*/
|
|
79
|
+
type: string;
|
|
80
|
+
/**
|
|
81
|
+
* The id in the URL: the record of a `show`, the owner of a relationship
|
|
82
|
+
* or related endpoint. None for a list.
|
|
83
|
+
*/
|
|
84
|
+
id?: string;
|
|
85
|
+
/** The relationship of a relationship or related endpoint (`comments`). */
|
|
86
|
+
relationship?: string;
|
|
87
|
+
};
|
|
88
|
+
/** A document a read answered with, for `onDocument`. */
|
|
89
|
+
export type AuditedDocument = {
|
|
90
|
+
/** The request, as a path and query string. */
|
|
91
|
+
url: string;
|
|
92
|
+
/** Its status. */
|
|
93
|
+
status: number;
|
|
94
|
+
/** The read the request was made to. */
|
|
95
|
+
route: AuditedRoute;
|
|
96
|
+
/** The parsed JSON:API document. */
|
|
97
|
+
document: Record<string, unknown>;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* What `onDocument` returns: a message for each problem found, or nothing
|
|
101
|
+
* when there is none.
|
|
102
|
+
*/
|
|
103
|
+
export type DocumentCheckResult = string | ReadonlyArray<string> | null | undefined | void;
|
|
104
|
+
/**
|
|
105
|
+
* A record a response contained that the audit's `visible` does not allow; a
|
|
106
|
+
* relationship or related endpoint that answered for an owner `visible` does
|
|
107
|
+
* not allow; a request that failed with an error other than `401`, `403` or
|
|
108
|
+
* `404`, so that what it serves could not be checked; or a problem
|
|
109
|
+
* `onDocument` found.
|
|
110
|
+
*/
|
|
111
|
+
export type VisibilityViolation = {
|
|
112
|
+
/** The request, as a path and query string. */
|
|
113
|
+
url: string;
|
|
114
|
+
/** Its status. */
|
|
115
|
+
status: number;
|
|
116
|
+
/**
|
|
117
|
+
* The record's type, if the violation is a record: one the response named,
|
|
118
|
+
* or the hidden owner an endpoint answered for.
|
|
119
|
+
*/
|
|
120
|
+
type?: string;
|
|
121
|
+
/** The record's id, if the violation is a record. */
|
|
122
|
+
id?: string;
|
|
123
|
+
/**
|
|
124
|
+
* What is wrong, for a hidden owner an endpoint answered for and for what
|
|
125
|
+
* `onDocument` found.
|
|
126
|
+
*/
|
|
127
|
+
message?: string;
|
|
128
|
+
};
|
|
129
|
+
/** What {@link auditVisibility} found. */
|
|
130
|
+
export type VisibilityAudit = {
|
|
131
|
+
/** Every request made, as a path and query string. */
|
|
132
|
+
requests: Array<string>;
|
|
133
|
+
/** What should not have been in a response, in request order. */
|
|
134
|
+
violations: Array<VisibilityViolation>;
|
|
135
|
+
/**
|
|
136
|
+
* Every record the responses named, keyed by type: as primary data,
|
|
137
|
+
* included or as linkage, allowed or not, each id once. Compare it with
|
|
138
|
+
* what the request should see to check that the audit reached it all.
|
|
139
|
+
*/
|
|
140
|
+
seen: Record<string, Array<string>>;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Request every read a namespace serves — each list, each record by id, each
|
|
144
|
+
* relationship and related endpoint, without `include` and with every path
|
|
145
|
+
* it accepts, following every page — and report each record in a response that
|
|
146
|
+
* `visible` does not allow: in `data`, in `included`, or in any
|
|
147
|
+
* relationship's linkage. A relationship or related endpoint that answers
|
|
148
|
+
* for an owner `visible` does not allow is reported too, whatever it
|
|
149
|
+
* answers with: that it answers reveals the owner. A `401`, `403` or `404`
|
|
150
|
+
* (for a hidden record) reveals nothing and passes; any other error is
|
|
151
|
+
* reported, since the read it answers went unchecked.
|
|
152
|
+
*
|
|
153
|
+
* Visibility rules apply to every one of these paths, but scoping in an
|
|
154
|
+
* `index` or `show` override, or in a hook keyed on the action, does not.
|
|
155
|
+
* This checks the result rather than the mechanism, against a list written
|
|
156
|
+
* by hand:
|
|
157
|
+
*
|
|
158
|
+
* ```javascript
|
|
159
|
+
* import { auditVisibility } from 'lumen-framework/testing';
|
|
160
|
+
*
|
|
161
|
+
* it('shows a member only public posts and their comments', async () => {
|
|
162
|
+
* const { violations } = await auditVisibility(app, {
|
|
163
|
+
* namespace: 'members',
|
|
164
|
+
* headers: { Authorization: `Bearer ${memberToken}` },
|
|
165
|
+
* visible: {
|
|
166
|
+
* posts: [publicPost.id],
|
|
167
|
+
* comments: [commentOnPublicPost.id],
|
|
168
|
+
* users: true
|
|
169
|
+
* }
|
|
170
|
+
* });
|
|
171
|
+
*
|
|
172
|
+
* expect(violations).toEqual([]);
|
|
173
|
+
* });
|
|
174
|
+
* ```
|
|
175
|
+
*
|
|
176
|
+
* Requests are made one at a time, to `app` itself (which must then be
|
|
177
|
+
* listening, as {@link startApp} leaves it) or to `origin`. Custom routes are
|
|
178
|
+
* not requested. Each route is requested once per
|
|
179
|
+
* id (and per page), so run it against a small fixture database, or narrow
|
|
180
|
+
* the ids with `ids`.
|
|
181
|
+
*
|
|
182
|
+
* @param app - The application, listening.
|
|
183
|
+
* @param options - What to audit, and what the request may see.
|
|
184
|
+
* @returns Every request made, every violation found, and every record
|
|
185
|
+
* seen.
|
|
186
|
+
* @throws When the namespace serves no reads, so a mistyped namespace cannot
|
|
187
|
+
* pass by checking nothing.
|
|
188
|
+
*/
|
|
189
|
+
export default function auditVisibility(app: Application, { namespace, visible, headers, ids, query: required, origin, onDocument }: AuditVisibilityOptions): Promise<VisibilityAudit>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as auditVisibility } from './audit-visibility';
|
|
2
|
+
export { default as startApp } from './start-app';
|
|
3
|
+
export type { StartAppOptions, StartedApp } from './start-app';
|
|
4
|
+
export type { AuditedDocument, AuditedRoute, AuditVisibilityOptions, DocumentCheckResult, VisibilityAudit, VisibilityViolation, VisibleRecords } from './audit-visibility';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type Application from '../application';
|
|
2
|
+
/** The options of {@link startApp}. */
|
|
3
|
+
export type StartAppOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* The environment to boot in: which `config/environments/*.js` and which
|
|
6
|
+
* entry of `config/database.js` apply. Sets `NODE_ENV` when given, and
|
|
7
|
+
* defaults it to `'test'` when unset, until `close()` restores it.
|
|
8
|
+
*/
|
|
9
|
+
env?: string;
|
|
10
|
+
/** The port to listen on. `0`, the default, takes a free one. */
|
|
11
|
+
port?: number;
|
|
12
|
+
};
|
|
13
|
+
/** An application {@link startApp} booted. */
|
|
14
|
+
export type StartedApp = {
|
|
15
|
+
/** The application, for {@link auditVisibility} and the models. */
|
|
16
|
+
app: Application;
|
|
17
|
+
/** Where it listens, such as `'http://localhost:53017'`. */
|
|
18
|
+
origin: string;
|
|
19
|
+
/**
|
|
20
|
+
* Stops the server, closes the database connections, and restores
|
|
21
|
+
* `NODE_ENV` to what it was before `startApp()`.
|
|
22
|
+
*/
|
|
23
|
+
close: () => Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Boot the app at `path` in the test's own process, from its compiled
|
|
27
|
+
* bundle (`dist/bundle.js`), and listen on a free port.
|
|
28
|
+
*
|
|
29
|
+
* ```javascript
|
|
30
|
+
* import { startApp } from 'lumen-framework/testing';
|
|
31
|
+
*
|
|
32
|
+
* let app, origin, close;
|
|
33
|
+
*
|
|
34
|
+
* beforeAll(async () => {
|
|
35
|
+
* ({ app, origin, close } = await startApp(process.cwd()));
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* afterAll(() => close());
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* The bundle must be compiled for the environment first, as `lumen build`
|
|
42
|
+
* and the `lumen db:*` commands do. Its model classes are set up once per
|
|
43
|
+
* process, so start an app once and share it between test files; starting
|
|
44
|
+
* the same one again throws. `NODE_ENV` holds the app's environment until
|
|
45
|
+
* `close()`.
|
|
46
|
+
*
|
|
47
|
+
* @param path - The app's root directory.
|
|
48
|
+
* @param options - The environment and port.
|
|
49
|
+
* @returns The application, where it listens, and how to stop it.
|
|
50
|
+
* @throws When the app at `path` was already started in this process.
|
|
51
|
+
*/
|
|
52
|
+
export default function startApp(path: string, { env, port }?: StartAppOptions): Promise<StartedApp>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** A resource's `type` and `id`. */
|
|
2
|
+
export type Identifier = {
|
|
3
|
+
type: string;
|
|
4
|
+
id: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Every resource a JSON:API document names: its primary data, its `included`
|
|
8
|
+
* resources, and the linkage of each one's relationships. A relationship
|
|
9
|
+
* endpoint's primary data is linkage itself, so it is covered the same way.
|
|
10
|
+
* Ids are strings, as JSON:API sends them.
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export default function identifiersIn(document: unknown): Array<Identifier>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for an app's tests, imported from `lumen-framework/testing`. They
|
|
3
|
+
* are kept out of the main entry, so they never reach an app's runtime
|
|
4
|
+
* bundle.
|
|
5
|
+
*
|
|
6
|
+
* @module lumen-framework/testing
|
|
7
|
+
*/
|
|
8
|
+
export { auditVisibility, startApp } from './packages/testing';
|
|
9
|
+
export type { AuditedDocument, AuditedRoute, AuditVisibilityOptions, DocumentCheckResult, StartAppOptions, StartedApp, VisibilityAudit, VisibilityViolation, VisibleRecords } from './packages/testing';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The framework's chalk instance — equivalent to chalk's default export, which
|
|
3
|
+
* is itself a `Chalk` built without options (same colour-level detection).
|
|
4
|
+
*
|
|
5
|
+
* Built from the *named* `Chalk` export on purpose. chalk is ESM-only from v5
|
|
6
|
+
* on, and the app compiler re-bundles `dist/index.mjs` to CommonJS. Importing
|
|
7
|
+
* from an ES module, esbuild gives a default import Node's CommonJS semantics
|
|
8
|
+
* (the whole `require()` result), and `require()` of an ES module returns its
|
|
9
|
+
* namespace — so `import chalk from 'chalk'` would make `chalk.yellow`
|
|
10
|
+
* undefined inside an app. Named imports resolve correctly either way. An
|
|
11
|
+
* ESLint rule keeps the default import out of `src/`.
|
|
12
|
+
*
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
declare const chalk: import("chalk").ChalkInstance;
|
|
16
|
+
export default chalk;
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The result is `Partial<T>` rather than Flow's `T`: keys may be dropped, both
|
|
5
5
|
* because the caller asked for a subset and because undefined values are
|
|
6
|
-
* filtered out. The
|
|
7
|
-
* access makes the shape unknowable to the compiler.
|
|
6
|
+
* filtered out. The casts are confined to the boundaries, where the dynamic
|
|
7
|
+
* key access makes the shape unknowable to the compiler.
|
|
8
8
|
*
|
|
9
9
|
* @private
|
|
10
10
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lumen-framework",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Build scalable, Node.js-powered REST APIs with almost no code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mvc",
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
"bugs": {
|
|
16
16
|
"url": "https://github.com/nickschot/lux/issues"
|
|
17
17
|
},
|
|
18
|
-
"repository":
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "github:nickschot/lux"
|
|
21
|
+
},
|
|
19
22
|
"license": "MIT",
|
|
20
23
|
"author": "Nick Schot <nickschot@gmail.com>",
|
|
21
24
|
"contributors": [
|
|
@@ -27,6 +30,19 @@
|
|
|
27
30
|
"main": "dist/index.js",
|
|
28
31
|
"module": "dist/index.mjs",
|
|
29
32
|
"types": "./dist/types/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/types/index.d.ts",
|
|
36
|
+
"module": "./dist/index.mjs",
|
|
37
|
+
"default": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./testing": {
|
|
40
|
+
"types": "./dist/types/testing.d.ts",
|
|
41
|
+
"module": "./dist/testing.mjs",
|
|
42
|
+
"default": "./dist/testing.js"
|
|
43
|
+
},
|
|
44
|
+
"./package.json": "./package.json"
|
|
45
|
+
},
|
|
30
46
|
"bin": {
|
|
31
47
|
"lumen": "bin/lumen"
|
|
32
48
|
},
|
|
@@ -37,46 +53,58 @@
|
|
|
37
53
|
"LICENSE"
|
|
38
54
|
],
|
|
39
55
|
"dependencies": {
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"esbuild": "^0.28.1",
|
|
56
|
+
"chalk": "^6.0.1",
|
|
57
|
+
"commander": "^15.0.0",
|
|
58
|
+
"esbuild": "^0.28.2",
|
|
44
59
|
"fb-watchman": "^2.0.2",
|
|
45
|
-
"inflection": "^
|
|
60
|
+
"inflection": "^3.0.2",
|
|
46
61
|
"knex": "^3.3.0",
|
|
47
|
-
"ora": "^
|
|
62
|
+
"ora": "^9.4.1"
|
|
48
63
|
},
|
|
49
64
|
"devDependencies": {
|
|
50
|
-
"@eslint/js": "^
|
|
51
|
-
"@
|
|
52
|
-
"@types/node": "^20.
|
|
53
|
-
"@vitest/coverage-v8": "^
|
|
54
|
-
"
|
|
65
|
+
"@eslint/js": "^10.0.1",
|
|
66
|
+
"@faker-js/faker": "^10.6.0",
|
|
67
|
+
"@types/node": "^22.20.5",
|
|
68
|
+
"@vitest/coverage-v8": "^5.0.3",
|
|
69
|
+
"ajv": "^8.20.0",
|
|
70
|
+
"ajv-formats": "^3.0.1",
|
|
71
|
+
"eslint": "^10.12.0",
|
|
55
72
|
"eslint-config-prettier": "^10.1.8",
|
|
56
|
-
"
|
|
57
|
-
"globals": "^17.7.0",
|
|
73
|
+
"globals": "^17.13.0",
|
|
58
74
|
"lumen-framework": "link:.",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
75
|
+
"prettier": "^3.9.9",
|
|
76
|
+
"release-plan": "^0.20.1",
|
|
77
|
+
"shx": "^0.4.0",
|
|
78
|
+
"sinon": "22.1.0",
|
|
79
|
+
"typedoc": "^0.28.20",
|
|
64
80
|
"typescript": "^6.0.3",
|
|
65
|
-
"typescript-eslint": "^8.
|
|
66
|
-
"vitest": "^
|
|
81
|
+
"typescript-eslint": "^8.71.1",
|
|
82
|
+
"vitest": "^5.0.3"
|
|
67
83
|
},
|
|
68
84
|
"engines": {
|
|
69
|
-
"node": ">=
|
|
85
|
+
"node": ">= 22.14"
|
|
70
86
|
},
|
|
71
|
-
"
|
|
72
|
-
"
|
|
87
|
+
"devEngines": {
|
|
88
|
+
"runtime": [
|
|
89
|
+
{
|
|
90
|
+
"name": "node",
|
|
91
|
+
"version": "22.23.3",
|
|
92
|
+
"onFail": "download"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"name": "node",
|
|
96
|
+
"version": ">=22.14",
|
|
97
|
+
"onFail": "warn"
|
|
98
|
+
}
|
|
99
|
+
]
|
|
73
100
|
},
|
|
74
101
|
"scripts": {
|
|
75
102
|
"build": "node build.mjs",
|
|
76
103
|
"build:debugger": "node test/utils/debugger/build.mjs",
|
|
77
104
|
"build:types": "tsc -p tsconfig.build.json",
|
|
78
|
-
"clean": "shx rm -rf coverage dist test/test-app/dist",
|
|
105
|
+
"clean": "shx rm -rf coverage dist docs/api test/test-app/dist",
|
|
79
106
|
"debugger": "node --enable-source-maps test/utils/debugger/dist/debug.js",
|
|
107
|
+
"docs:api": "typedoc",
|
|
80
108
|
"format": "prettier --write .",
|
|
81
109
|
"format:check": "prettier --check .",
|
|
82
110
|
"lint": "eslint .",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function hasOwnProperty(target: object, key: string): boolean;
|