@gettersethya/mira 0.1.0-alpha.15 → 0.1.0-alpha.17
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 +33 -9
- package/dist/src/app/app.d.ts +30 -18
- package/dist/src/app/app.d.ts.map +1 -1
- package/dist/src/app/app.js +50 -30
- package/dist/src/app/app.js.map +1 -1
- package/dist/src/app/builder.d.ts +19 -7
- package/dist/src/app/builder.d.ts.map +1 -1
- package/dist/src/app/builder.js +23 -3
- package/dist/src/app/builder.js.map +1 -1
- package/dist/src/app/define-rule.d.ts +70 -0
- package/dist/src/app/define-rule.d.ts.map +1 -0
- package/dist/src/app/define-rule.js +41 -0
- package/dist/src/app/define-rule.js.map +1 -0
- package/dist/src/app/index.d.ts +6 -3
- package/dist/src/app/index.d.ts.map +1 -1
- package/dist/src/app/index.js +2 -0
- package/dist/src/app/index.js.map +1 -1
- package/dist/src/app/plugin.d.ts +6 -9
- package/dist/src/app/plugin.d.ts.map +1 -1
- package/dist/src/app/plugin.js.map +1 -1
- package/dist/src/app/types.d.ts +4 -4
- package/dist/src/app/types.d.ts.map +1 -1
- package/dist/src/cache/cached-collection.d.ts +7 -5
- package/dist/src/cache/cached-collection.d.ts.map +1 -1
- package/dist/src/cache/cached-collection.js +5 -2
- package/dist/src/cache/cached-collection.js.map +1 -1
- package/dist/src/cache/collection-cache.d.ts +1 -1
- package/dist/src/cache/collection-cache.d.ts.map +1 -1
- package/dist/src/cache/collection-cache.js +1 -1
- package/dist/src/cache/collection-cache.js.map +1 -1
- package/dist/src/cache/ctx-key.d.ts +15 -0
- package/dist/src/cache/ctx-key.d.ts.map +1 -0
- package/dist/src/cache/ctx-key.js +37 -0
- package/dist/src/cache/ctx-key.js.map +1 -0
- package/dist/src/cache/index.d.ts +2 -1
- package/dist/src/cache/index.d.ts.map +1 -1
- package/dist/src/cache/index.js +2 -1
- package/dist/src/cache/index.js.map +1 -1
- package/dist/src/collection-service/collection-service.d.ts +7 -5
- package/dist/src/collection-service/collection-service.d.ts.map +1 -1
- package/dist/src/collection-service/collection-service.js +65 -24
- package/dist/src/collection-service/collection-service.js.map +1 -1
- package/dist/src/collection-service/decode.d.ts +4 -2
- package/dist/src/collection-service/decode.d.ts.map +1 -1
- package/dist/src/collection-service/decode.js +32 -16
- package/dist/src/collection-service/decode.js.map +1 -1
- package/dist/src/collection-service/errors.d.ts +1 -1
- package/dist/src/collection-service/errors.d.ts.map +1 -1
- package/dist/src/collection-service/errors.js +1 -1
- package/dist/src/collection-service/errors.js.map +1 -1
- package/dist/src/collection-service/index.d.ts +1 -1
- package/dist/src/collection-service/index.d.ts.map +1 -1
- package/dist/src/collection-service/index.js.map +1 -1
- package/dist/src/collection-service/input-schema.d.ts +5 -4
- package/dist/src/collection-service/input-schema.d.ts.map +1 -1
- package/dist/src/collection-service/input-schema.js +21 -22
- package/dist/src/collection-service/input-schema.js.map +1 -1
- package/dist/src/collection-service/where.d.ts +14 -2
- package/dist/src/collection-service/where.d.ts.map +1 -1
- package/dist/src/collection-service/where.js +32 -1
- package/dist/src/collection-service/where.js.map +1 -1
- package/dist/src/config/config.d.ts +4 -4
- package/dist/src/config/config.d.ts.map +1 -1
- package/dist/src/config/config.js +33 -5
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/types.d.ts +8 -0
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/cron/cron-service.d.ts +4 -4
- package/dist/src/cron/cron-service.d.ts.map +1 -1
- package/dist/src/cron/cron-service.js +14 -14
- package/dist/src/cron/cron-service.js.map +1 -1
- package/dist/src/cron/index.d.ts +1 -1
- package/dist/src/cron/index.d.ts.map +1 -1
- package/dist/src/cron/persistence.d.ts +8 -8
- package/dist/src/cron/persistence.d.ts.map +1 -1
- package/dist/src/cron/persistence.js +6 -6
- package/dist/src/cron/persistence.js.map +1 -1
- package/dist/src/cron/types.d.ts +3 -3
- package/dist/src/cron/types.d.ts.map +1 -1
- package/dist/src/cron/types.js.map +1 -1
- package/dist/src/crypto/crypto.d.ts +3 -2
- package/dist/src/crypto/crypto.d.ts.map +1 -1
- package/dist/src/crypto/crypto.js +1 -1
- package/dist/src/crypto/crypto.js.map +1 -1
- package/dist/src/crypto/node.d.ts.map +1 -1
- package/dist/src/crypto/node.js.map +1 -1
- package/dist/src/databases/sqlite.d.ts.map +1 -1
- package/dist/src/databases/sqlite.js +2 -2
- package/dist/src/databases/sqlite.js.map +1 -1
- package/dist/src/dialect/dialect-sqlite.d.ts +9 -0
- package/dist/src/dialect/dialect-sqlite.d.ts.map +1 -0
- package/dist/src/dialect/dialect-sqlite.js +109 -0
- package/dist/src/dialect/dialect-sqlite.js.map +1 -0
- package/dist/src/dialect/dialect.d.ts +26 -0
- package/dist/src/dialect/dialect.d.ts.map +1 -0
- package/dist/src/dialect/dialect.js +5 -0
- package/dist/src/dialect/dialect.js.map +1 -0
- package/dist/src/hooks/hook-collection.d.ts.map +1 -1
- package/dist/src/hooks/hook-collection.js +15 -15
- package/dist/src/hooks/hook-collection.js.map +1 -1
- package/dist/src/hooks/hook-service.d.ts +3 -3
- package/dist/src/hooks/hook-service.d.ts.map +1 -1
- package/dist/src/hooks/hook-service.js +14 -14
- package/dist/src/hooks/hook-service.js.map +1 -1
- package/dist/src/hooks/index.d.ts +2 -2
- package/dist/src/hooks/index.d.ts.map +1 -1
- package/dist/src/hooks/index.js +1 -1
- package/dist/src/hooks/index.js.map +1 -1
- package/dist/src/hooks/types.d.ts.map +1 -1
- package/dist/src/http/auth-node.d.ts.map +1 -1
- package/dist/src/http/auth-node.js +1 -1
- package/dist/src/http/auth-node.js.map +1 -1
- package/dist/src/http/auth.d.ts +2 -2
- package/dist/src/http/auth.d.ts.map +1 -1
- package/dist/src/http/auth.js +2 -2
- package/dist/src/http/auth.js.map +1 -1
- package/dist/src/http/errors.d.ts +1 -1
- package/dist/src/http/errors.d.ts.map +1 -1
- package/dist/src/http/errors.js +7 -7
- package/dist/src/http/errors.js.map +1 -1
- package/dist/src/http/file-serve.d.ts +3 -3
- package/dist/src/http/file-serve.d.ts.map +1 -1
- package/dist/src/http/file-serve.js +21 -21
- package/dist/src/http/file-serve.js.map +1 -1
- package/dist/src/http/file-token.d.ts +4 -3
- package/dist/src/http/file-token.d.ts.map +1 -1
- package/dist/src/http/file-token.js +10 -10
- package/dist/src/http/file-token.js.map +1 -1
- package/dist/src/http/files.d.ts +3 -3
- package/dist/src/http/files.d.ts.map +1 -1
- package/dist/src/http/files.js +5 -5
- package/dist/src/http/files.js.map +1 -1
- package/dist/src/http/index.d.ts +5 -5
- package/dist/src/http/index.d.ts.map +1 -1
- package/dist/src/http/index.js +3 -3
- package/dist/src/http/index.js.map +1 -1
- package/dist/src/http/ip-middleware.d.ts +3 -2
- package/dist/src/http/ip-middleware.d.ts.map +1 -1
- package/dist/src/http/ip-middleware.js +1 -1
- package/dist/src/http/ip-middleware.js.map +1 -1
- package/dist/src/http/params.d.ts +3 -3
- package/dist/src/http/params.d.ts.map +1 -1
- package/dist/src/http/params.js +2 -2
- package/dist/src/http/params.js.map +1 -1
- package/dist/src/http/port-retry.d.ts +18 -0
- package/dist/src/http/port-retry.d.ts.map +1 -0
- package/dist/src/http/port-retry.js +43 -0
- package/dist/src/http/port-retry.js.map +1 -0
- package/dist/src/http/router.d.ts +10 -7
- package/dist/src/http/router.d.ts.map +1 -1
- package/dist/src/http/router.js +66 -41
- package/dist/src/http/router.js.map +1 -1
- package/dist/src/http/schema.d.ts +2 -2
- package/dist/src/http/schema.d.ts.map +1 -1
- package/dist/src/http/schema.js +14 -16
- package/dist/src/http/schema.js.map +1 -1
- package/dist/src/http/server-factory-node.d.ts.map +1 -1
- package/dist/src/http/server-factory-node.js +1 -1
- package/dist/src/http/server-factory-node.js.map +1 -1
- package/dist/src/http/server-factory.d.ts +3 -3
- package/dist/src/http/server-factory.d.ts.map +1 -1
- package/dist/src/http/server-factory.js +1 -1
- package/dist/src/http/server-factory.js.map +1 -1
- package/dist/src/http/telemetry-routes.d.ts +3 -3
- package/dist/src/http/telemetry-routes.d.ts.map +1 -1
- package/dist/src/http/telemetry-routes.js +130 -70
- package/dist/src/http/telemetry-routes.js.map +1 -1
- package/dist/src/index.d.ts +9 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/migrator/index.d.ts +4 -4
- package/dist/src/migrator/index.d.ts.map +1 -1
- package/dist/src/migrator/index.js +2 -2
- package/dist/src/migrator/index.js.map +1 -1
- package/dist/src/migrator/migrator.d.ts +9 -9
- package/dist/src/migrator/migrator.d.ts.map +1 -1
- package/dist/src/migrator/migrator.js +16 -13
- package/dist/src/migrator/migrator.js.map +1 -1
- package/dist/src/migrator/schema-diff.d.ts +2 -2
- package/dist/src/migrator/schema-diff.d.ts.map +1 -1
- package/dist/src/migrator/schema-diff.js.map +1 -1
- package/dist/src/migrator/types.d.ts +5 -5
- package/dist/src/migrator/types.d.ts.map +1 -1
- package/dist/src/migrator/types.js +6 -7
- package/dist/src/migrator/types.js.map +1 -1
- package/dist/src/platforms/node.d.ts +1 -1
- package/dist/src/platforms/node.d.ts.map +1 -1
- package/dist/src/platforms/node.js +1 -1
- package/dist/src/platforms/node.js.map +1 -1
- package/dist/src/repository/id.d.ts.map +1 -1
- package/dist/src/repository/id.js.map +1 -1
- package/dist/src/repository/repository.d.ts +3 -2
- package/dist/src/repository/repository.d.ts.map +1 -1
- package/dist/src/repository/repository.js +5 -5
- package/dist/src/repository/repository.js.map +1 -1
- package/dist/src/rule/enforcer.d.ts.map +1 -1
- package/dist/src/rule/enforcer.js.map +1 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.d.ts.map +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/index.js.map +1 -1
- package/dist/src/storage/local-preset.d.ts.map +1 -1
- package/dist/src/storage/local-preset.js.map +1 -1
- package/dist/src/storage/storage.d.ts +2 -2
- package/dist/src/storage/storage.d.ts.map +1 -1
- package/dist/src/storage/storage.js +8 -26
- package/dist/src/storage/storage.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +15 -4
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/index.js +14 -6
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/logger.d.ts +29 -2
- package/dist/src/telemetry/logger.d.ts.map +1 -1
- package/dist/src/telemetry/logger.js +52 -15
- package/dist/src/telemetry/logger.js.map +1 -1
- package/dist/src/telemetry/sqlite-logger.d.ts +14 -6
- package/dist/src/telemetry/sqlite-logger.d.ts.map +1 -1
- package/dist/src/telemetry/sqlite-logger.js +81 -60
- package/dist/src/telemetry/sqlite-logger.js.map +1 -1
- package/dist/src/telemetry/telemetry-sql-client.d.ts +2 -2
- package/dist/src/telemetry/telemetry-sql-client.d.ts.map +1 -1
- package/dist/src/telemetry/telemetry-sql-client.js +1 -1
- package/dist/src/telemetry/telemetry-sql-client.js.map +1 -1
- package/dist/src/telemetry/tracer.d.ts +16 -1
- package/dist/src/telemetry/tracer.d.ts.map +1 -1
- package/dist/src/telemetry/tracer.js +87 -70
- package/dist/src/telemetry/tracer.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +11 -0
- package/dist/src/telemetry/types.d.ts.map +1 -0
- package/dist/src/telemetry/types.js +2 -0
- package/dist/src/telemetry/types.js.map +1 -0
- package/dist/src/thumbnail/index.d.ts +2 -2
- package/dist/src/thumbnail/index.d.ts.map +1 -1
- package/dist/src/thumbnail/index.js +1 -1
- package/dist/src/thumbnail/index.js.map +1 -1
- package/dist/src/thumbnail/photon.d.ts.map +1 -1
- package/dist/src/thumbnail/photon.js +1 -1
- package/dist/src/thumbnail/photon.js.map +1 -1
- package/dist/src/thumbnail/types.d.ts +1 -1
- package/dist/src/thumbnail/types.d.ts.map +1 -1
- package/dist/src/thumbnail/types.js +2 -2
- package/dist/src/thumbnail/types.js.map +1 -1
- package/dist/tests/app/app.test.js +62 -35
- package/dist/tests/app/app.test.js.map +1 -1
- package/dist/tests/app/builder.test.js +24 -4
- package/dist/tests/app/builder.test.js.map +1 -1
- package/dist/tests/app/define-rule.test.d.ts +2 -0
- package/dist/tests/app/define-rule.test.d.ts.map +1 -0
- package/dist/tests/app/define-rule.test.js +147 -0
- package/dist/tests/app/define-rule.test.js.map +1 -0
- package/dist/tests/cache/cached-collection.test.js +200 -40
- package/dist/tests/cache/cached-collection.test.js.map +1 -1
- package/dist/tests/cache/collection-cache.test.js +1 -1
- package/dist/tests/cache/collection-cache.test.js.map +1 -1
- package/dist/tests/collection-service/collection-service.test.js +283 -216
- package/dist/tests/collection-service/collection-service.test.js.map +1 -1
- package/dist/tests/collection-service/decode.test.d.ts +2 -0
- package/dist/tests/collection-service/decode.test.d.ts.map +1 -0
- package/dist/tests/collection-service/decode.test.js +37 -0
- package/dist/tests/collection-service/decode.test.js.map +1 -0
- package/dist/tests/collection-service/input-schema.test.js +121 -121
- package/dist/tests/collection-service/input-schema.test.js.map +1 -1
- package/dist/tests/config/config.test.js +15 -4
- package/dist/tests/config/config.test.js.map +1 -1
- package/dist/tests/cron/cron-integration.test.js +5 -5
- package/dist/tests/cron/cron-integration.test.js.map +1 -1
- package/dist/tests/cron/cron-persistence.test.js +11 -11
- package/dist/tests/cron/cron-persistence.test.js.map +1 -1
- package/dist/tests/cron/cron-service.test.js +11 -10
- package/dist/tests/cron/cron-service.test.js.map +1 -1
- package/dist/tests/crypto/crypto.test.js +2 -2
- package/dist/tests/crypto/crypto.test.js.map +1 -1
- package/dist/tests/hooks/hook-collection.test.js +22 -15
- package/dist/tests/hooks/hook-collection.test.js.map +1 -1
- package/dist/tests/hooks/hook-service.test.js +9 -6
- package/dist/tests/hooks/hook-service.test.js.map +1 -1
- package/dist/tests/http/file-serve.test.js +62 -54
- package/dist/tests/http/file-serve.test.js.map +1 -1
- package/dist/tests/http/file-token.test.js +62 -55
- package/dist/tests/http/file-token.test.js.map +1 -1
- package/dist/tests/http/ip-middleware.test.js +13 -13
- package/dist/tests/http/ip-middleware.test.js.map +1 -1
- package/dist/tests/http/port-retry.test.d.ts +2 -0
- package/dist/tests/http/port-retry.test.d.ts.map +1 -0
- package/dist/tests/http/port-retry.test.js +52 -0
- package/dist/tests/http/port-retry.test.js.map +1 -0
- package/dist/tests/http/router.test.js +137 -96
- package/dist/tests/http/router.test.js.map +1 -1
- package/dist/tests/migrator/dialect-sqlite.test.js +1 -1
- package/dist/tests/migrator/dialect-sqlite.test.js.map +1 -1
- package/dist/tests/migrator/integration.test.js +6 -6
- package/dist/tests/migrator/integration.test.js.map +1 -1
- package/dist/tests/migrator/migrator.test.js +5 -5
- package/dist/tests/migrator/migrator.test.js.map +1 -1
- package/dist/tests/migrator/schema-diff.test.js.map +1 -1
- package/dist/tests/repository/repository.test.js +10 -8
- package/dist/tests/repository/repository.test.js.map +1 -1
- package/dist/tests/rule/compiler.test.js +1 -1
- package/dist/tests/rule/compiler.test.js.map +1 -1
- package/dist/tests/rule/enforcer.test.js +9 -9
- package/dist/tests/rule/enforcer.test.js.map +1 -1
- package/dist/tests/storage/storage.test.js +15 -15
- package/dist/tests/storage/storage.test.js.map +1 -1
- package/dist/tests/telemetry/collections.test.js +1 -1
- package/dist/tests/telemetry/collections.test.js.map +1 -1
- package/dist/tests/telemetry/instrumentation.test.js +27 -20
- package/dist/tests/telemetry/instrumentation.test.js.map +1 -1
- package/dist/tests/telemetry/logger.test.js +38 -6
- package/dist/tests/telemetry/logger.test.js.map +1 -1
- package/dist/tests/telemetry/sqlite-logger.test.js +5 -5
- package/dist/tests/telemetry/sqlite-logger.test.js.map +1 -1
- package/dist/tests/telemetry/telemetry-routes.test.js +29 -8
- package/dist/tests/telemetry/telemetry-routes.test.js.map +1 -1
- package/dist/tests/telemetry/tracer.test.js +41 -4
- package/dist/tests/telemetry/tracer.test.js.map +1 -1
- package/dist/tests/thumbnail/photon.test.js +35 -35
- package/dist/tests/thumbnail/photon.test.js.map +1 -1
- package/dist/tests/thumbnail/thumbnail.test.js +7 -7
- package/dist/tests/thumbnail/thumbnail.test.js.map +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# @gettersethya/mira
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@gettersethya/mira)
|
|
4
|
+
|
|
3
5
|
> **Early pre-alpha.** Breaking changes may occur without notice.
|
|
4
6
|
|
|
5
|
-
Self-hosted backend in TypeScript using [Effect](https://effect.website). Define collections, get a full REST API with auth, file storage, access rules, and schema migrations — all with zero config.
|
|
7
|
+
Self-hosted backend in TypeScript using [Effect v4](https://effect.website). Define collections, get a full REST API with auth, file storage, access rules, and schema migrations — all with zero config.
|
|
6
8
|
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
@@ -15,20 +17,39 @@ pnpm add @gettersethya/mira @gettersethya/mira-collection effect
|
|
|
15
17
|
## Quick start
|
|
16
18
|
|
|
17
19
|
```typescript
|
|
18
|
-
import { LocalFileStorage, Mira, NodePlatform, SqliteDatabase } from "@gettersethya/mira"
|
|
20
|
+
import { defineRule, LocalFileStorage, Mira, NodePlatform, Rule, SqliteDatabase } from "@gettersethya/mira"
|
|
19
21
|
import { Posts, Users } from "./collections.js"
|
|
20
22
|
|
|
23
|
+
const userRules = defineRule(Users, (R) => ({
|
|
24
|
+
list: Rule.public(),
|
|
25
|
+
view: Rule.public(),
|
|
26
|
+
create: Rule.public(),
|
|
27
|
+
update: R.selfId().eq(R.authId(Users)),
|
|
28
|
+
}))
|
|
29
|
+
|
|
30
|
+
const postRules = defineRule(Posts, (R) => ({
|
|
31
|
+
list: R.field("published").eq(R.literal(true)),
|
|
32
|
+
view: R.or(
|
|
33
|
+
R.field("published").eq(R.literal(true)),
|
|
34
|
+
R.field("authorId").eq(R.authId(Users))
|
|
35
|
+
),
|
|
36
|
+
create: R.authId(Users).neq(R.literal(null)),
|
|
37
|
+
update: R.field("authorId").eq(R.authId(Users)),
|
|
38
|
+
delete: R.field("authorId").eq(R.authId(Users)),
|
|
39
|
+
}))
|
|
40
|
+
|
|
21
41
|
const app = Mira.builder()
|
|
22
42
|
.platform(NodePlatform)
|
|
23
43
|
.database(SqliteDatabase({ filename: "mira.db" }))
|
|
24
44
|
.storage(LocalFileStorage({ directory: "./uploads" }))
|
|
25
45
|
.collections([Users, Posts])
|
|
46
|
+
.rules([userRules, postRules])
|
|
26
47
|
.build()
|
|
27
48
|
|
|
28
49
|
app.serve({ port: 3000 })
|
|
29
50
|
```
|
|
30
51
|
|
|
31
|
-
The builder uses phantom types to enforce step ordering — TypeScript will not let you call `.build()` until all four steps are complete.
|
|
52
|
+
The builder uses phantom types to enforce step ordering — TypeScript will not let you call `.build()` until all four required steps are complete.
|
|
32
53
|
|
|
33
54
|
On first boot, Mira auto-generates a `jwt_secret`, runs schema migrations, and creates SQL views for view collections. Everything is persisted in the database.
|
|
34
55
|
|
|
@@ -40,6 +61,7 @@ On first boot, Mira auto-generates a `jwt_secret`, runs schema migrations, and c
|
|
|
40
61
|
| `.database(d)` | Yes | Database backend |
|
|
41
62
|
| `.storage(s)` | Yes | File storage backend |
|
|
42
63
|
| `.collections(c)` | Yes | Collection definitions |
|
|
64
|
+
| `.rules(r)` | No | Array of `RuleBinding` from `defineRule(collection, cb)` |
|
|
43
65
|
| `.crons(c)` | No | Array of `CronDef` — scheduled tasks using Effect `Schedule` |
|
|
44
66
|
| `.telemetry(layer)` | No | Custom Effect telemetry layer |
|
|
45
67
|
| `.extend(plugin)` | No | Register a `MiraPlugin` (lifecycle hooks, routes, crons, layers) |
|
|
@@ -75,15 +97,17 @@ Each collection gets a full set of REST endpoints:
|
|
|
75
97
|
|
|
76
98
|
| Method | Path | Description |
|
|
77
99
|
|---|---|---|
|
|
78
|
-
| `GET` | `/api/:collection` | List (filter, sort, cursor, expand, select) |
|
|
79
|
-
| `GET` | `/api/:collection/:id` | Get one |
|
|
80
|
-
| `POST` | `/api/:collection` | Create |
|
|
81
|
-
| `PATCH` | `/api/:collection/:id` | Update |
|
|
82
|
-
| `DELETE` | `/api/:collection/:id` | Delete |
|
|
83
|
-
| `POST` | `/api/:collection/
|
|
100
|
+
| `GET` | `/api/collections/:collection` | List (filter, sort, cursor, expand, select) |
|
|
101
|
+
| `GET` | `/api/collections/:collection/:id` | Get one |
|
|
102
|
+
| `POST` | `/api/collections/:collection` | Create |
|
|
103
|
+
| `PATCH` | `/api/collections/:collection/:id` | Update |
|
|
104
|
+
| `DELETE` | `/api/collections/:collection/:id` | Delete |
|
|
105
|
+
| `POST` | `/api/collections/:collection/auth-with-password` | Login (auth collections only) |
|
|
106
|
+
| `GET` | `/api/auth/me` | Current authenticated record |
|
|
84
107
|
| `POST` | `/api/auth/logout` | Logout |
|
|
85
108
|
| `POST` | `/api/files/token` | Request protected file token |
|
|
86
109
|
| `GET` | `/api/files/:collection/:id/:filename` | Serve file |
|
|
110
|
+
| `GET` | `/api/_schema` | Schema introspection |
|
|
87
111
|
|
|
88
112
|
## Cron jobs
|
|
89
113
|
|
package/dist/src/app/app.d.ts
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AnyCollectionDef } from "@gettersethya/mira-client";
|
|
2
2
|
import { Layer } from "effect";
|
|
3
|
-
import { Migrator } from "../migrator/migrator.js";
|
|
4
3
|
import { AppConfig } from "../config/index.js";
|
|
5
|
-
import
|
|
6
|
-
import type { CollectionService } from "../collection-service/collection-service.js";
|
|
4
|
+
import { Migrator } from "../migrator/migrator.js";
|
|
7
5
|
import type { MiraAppConfig } from "./builder.js";
|
|
6
|
+
import type { RuleBinding } from "./define-rule.js";
|
|
8
7
|
import type { MiraPlugin } from "./plugin.js";
|
|
9
|
-
|
|
8
|
+
export declare function applyRulesToCollections(collections: ReadonlyArray<AnyCollectionDef>, rules: ReadonlyArray<RuleBinding>): Array<AnyCollectionDef>;
|
|
9
|
+
/**
|
|
10
|
+
* Options for `MiraApp.serve()` and `MiraApp.buildLayer()`.
|
|
11
|
+
*/
|
|
12
|
+
export interface ServeOptions {
|
|
13
|
+
/** Port to listen on. Defaults to the port from `AppConfig`. */
|
|
14
|
+
port?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Total number of ports to try when the requested port is already in use.
|
|
17
|
+
* The server increments the port and retries until a free one is found.
|
|
18
|
+
* Defaults to 10. Pass `1` to disable retrying.
|
|
19
|
+
*/
|
|
20
|
+
maxPortAttempts?: number;
|
|
21
|
+
}
|
|
10
22
|
/**
|
|
11
23
|
* The assembled Mira application, ready to serve.
|
|
12
24
|
*
|
|
@@ -47,12 +59,12 @@ export declare class MiraApp<R = never> {
|
|
|
47
59
|
* collection definitions.
|
|
48
60
|
*
|
|
49
61
|
* @param plugin - A MiraPlugin (use `fromLayer()` to wrap a plain Layer)
|
|
50
|
-
* @returns this
|
|
62
|
+
* @returns this (for chaining)
|
|
51
63
|
*
|
|
52
64
|
* @example
|
|
53
65
|
* app.extend(MiraDashboard).serve()
|
|
54
66
|
*/
|
|
55
|
-
extend
|
|
67
|
+
extend(plugin: MiraPlugin<any>): MiraApp<R>;
|
|
56
68
|
/**
|
|
57
69
|
* Build the full service layer without the HTTP server.
|
|
58
70
|
* Useful for testing — you can run Effects against the service layer without
|
|
@@ -69,33 +81,33 @@ export declare class MiraApp<R = never> {
|
|
|
69
81
|
* Effect.gen(function* () { ... }).pipe(Effect.provide(serviceLayer))
|
|
70
82
|
* )
|
|
71
83
|
*/
|
|
72
|
-
buildServiceLayer(): Layer.Layer<
|
|
84
|
+
buildServiceLayer(): Layer.Layer<import("../index.js").FileStorage | import("./types.js").PlatformServices | import("./types.js").DatabaseServices | import("../repository/repository.js").Repository | import("../index.js").CollectionService | AppConfig | Migrator | import("../cron/cron-service.js").CronService | import("../thumbnail/index.js").ThumbnailService, import("effect/sql/SqlError").SqlError | import("effect/Schema").SchemaError, any>;
|
|
73
85
|
/**
|
|
74
86
|
* Build the complete server layer including the HTTP router and server.
|
|
75
87
|
* Accepts an optional port override (otherwise uses the port from AppConfig).
|
|
76
88
|
*
|
|
77
|
-
* @param options
|
|
89
|
+
* @param options - Optional serve options (`port`, `maxPortAttempts`)
|
|
78
90
|
* @returns A Layer ready to be launched
|
|
79
91
|
*
|
|
80
92
|
* @internal Called by serve() — most users should use serve() directly.
|
|
81
93
|
*/
|
|
82
|
-
buildLayer(options?:
|
|
83
|
-
port?: number;
|
|
84
|
-
}): Layer.Layer<Migrator | AppConfig | HttpServer.HttpServer | import("@effect/platform/HttpPlatform").HttpPlatform | import("@effect/platform/Etag").Generator | import("../index.js").FileStorage | import("./types.js").PlatformServices | import("./types.js").DatabaseServices | Repository | CollectionService | import("../thumbnail/index.js").ThumbnailService | CronService, import("effect/ParseResult").ParseError | import("@effect/sql/SqlError").SqlError | import("@effect/platform/HttpServerError").ServeError, any>;
|
|
94
|
+
buildLayer(options?: ServeOptions): Layer.Layer<import("../index.js").FileStorage | import("./types.js").PlatformServices | import("./types.js").DatabaseServices | import("../repository/repository.js").Repository | import("../index.js").CollectionService | AppConfig | Migrator | import("../cron/cron-service.js").CronService | import("../thumbnail/index.js").ThumbnailService, import("effect/http/HttpServerError").ServeError | import("effect/sql/SqlError").SqlError | import("effect/Schema").SchemaError, any>;
|
|
85
95
|
/**
|
|
86
96
|
* Start the Mira HTTP server.
|
|
87
97
|
* Sets up all services, runs auto-migration, runs plugin lifecycle hooks,
|
|
88
98
|
* and listens for incoming requests.
|
|
89
99
|
* Blocks the main thread until the server is shut down.
|
|
90
100
|
*
|
|
91
|
-
*
|
|
101
|
+
* If the requested port is already in use, the server automatically retries
|
|
102
|
+
* on the next available port (up to `maxPortAttempts`, default 10).
|
|
103
|
+
*
|
|
104
|
+
* @param options - Optional serve options (`port`, `maxPortAttempts`)
|
|
92
105
|
*
|
|
93
106
|
* @example
|
|
94
|
-
* app.serve()
|
|
95
|
-
* app.serve({ port: 8080 })
|
|
107
|
+
* app.serve() // default port, auto-increment if busy
|
|
108
|
+
* app.serve({ port: 8080 }) // explicit port, auto-increment if busy
|
|
109
|
+
* app.serve({ port: 8080, maxPortAttempts: 1 }) // fail instead of incrementing
|
|
96
110
|
*/
|
|
97
|
-
serve(options?:
|
|
98
|
-
port?: number;
|
|
99
|
-
}): void;
|
|
111
|
+
serve(options?: ServeOptions): void;
|
|
100
112
|
}
|
|
101
113
|
//# sourceMappingURL=app.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/app/app.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/app/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAEjE,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAA;AAItC,OAAO,EAAE,SAAS,EAAiB,MAAM,mBAAmB,CAAA;AAU5D,OAAO,EAAE,QAAQ,EAAgB,MAAM,wBAAwB,CAAA;AAK/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAY7C,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,aAAa,CAAC,gBAAgB,CAAC,EAC5C,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAChC,KAAK,CAAC,gBAAgB,CAAC,CAkBzB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,OAAO,CAAC,CAAC,GAAG,KAAK;;gBAGhB,MAAM,EAAE,aAAa;IAKjC,+BAA+B;IAC/B,UAAU,IAAI,aAAa;IAI3B,+BAA+B;IAC/B,UAAU,IAAI,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAI5C;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqB3C;;;;;;;;;;;;;;;OAeG;IACH,iBAAiB;IAsDjB;;;;;;;;OAQG;IACH,UAAU,CAAC,OAAO,CAAC,EAAE,YAAY;IAwBjC;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;CAcpC"}
|
package/dist/src/app/app.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { HttpRouter, HttpServer } from "@effect/platform";
|
|
2
1
|
import { Effect, Layer } from "effect";
|
|
3
|
-
import {
|
|
4
|
-
import { Migrator, MigratorLive } from "../migrator/migrator.js";
|
|
2
|
+
import { HttpRouter } from "effect/http";
|
|
5
3
|
import { makeCachedCollectionServiceLayer } from "../cache/index.js";
|
|
6
|
-
import { makeCollectionRouter } from "../http/router.js";
|
|
7
|
-
import { ThumbnailServicePhotonLive } from "../thumbnail/index.js";
|
|
8
|
-
import { ipAnnotationMiddleware } from "../http/ip-middleware.js";
|
|
9
4
|
import { AppConfig, AppConfigLive } from "../config/index.js";
|
|
10
|
-
import {
|
|
11
|
-
import { makeHookServiceLayer } from "../hooks/hook-service.js";
|
|
5
|
+
import { makeCronServiceLayer } from "../cron/cron-service.js";
|
|
12
6
|
import { makeHookCollectionServiceLayer } from "../hooks/hook-collection.js";
|
|
7
|
+
import { makeHookServiceLayer } from "../hooks/hook-service.js";
|
|
13
8
|
import { HookService } from "../hooks/hook-service.js";
|
|
14
|
-
import {
|
|
9
|
+
import { ipAnnotationMiddleware } from "../http/ip-middleware.js";
|
|
10
|
+
import { makePortRetryServerLayer } from "../http/port-retry.js";
|
|
11
|
+
import { makeCollectionRouter } from "../http/router.js";
|
|
12
|
+
import { HttpServerFactory } from "../http/server-factory.js";
|
|
13
|
+
import { Migrator, MigratorLive } from "../migrator/migrator.js";
|
|
14
|
+
import { RepositoryLive } from "../repository/repository.js";
|
|
15
|
+
import { ThumbnailServicePhotonLive } from "../thumbnail/index.js";
|
|
15
16
|
function assertUniqueCronNames(defs) {
|
|
16
17
|
const seen = new Set();
|
|
17
18
|
for (const def of defs) {
|
|
@@ -21,6 +22,23 @@ function assertUniqueCronNames(defs) {
|
|
|
21
22
|
seen.add(def.name);
|
|
22
23
|
}
|
|
23
24
|
}
|
|
25
|
+
export function applyRulesToCollections(collections, rules) {
|
|
26
|
+
const collectionNames = new Set(collections.map((c) => c.name));
|
|
27
|
+
for (const rb of rules) {
|
|
28
|
+
if (!collectionNames.has(rb.collectionName)) {
|
|
29
|
+
throw new Error(`RuleBinding references unknown collection "${rb.collectionName}". ` +
|
|
30
|
+
`Available collections: ${[...collectionNames].join(", ")}.`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const ruleMap = new Map(rules.map((r) => [r.collectionName, r.ruleMap]));
|
|
34
|
+
return collections.map((c) => {
|
|
35
|
+
const rm = ruleMap.get(c.name);
|
|
36
|
+
if (rm) {
|
|
37
|
+
return { ...c, schema: { ...c.schema, "x-rules": rm } };
|
|
38
|
+
}
|
|
39
|
+
return c;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
24
42
|
/**
|
|
25
43
|
* The assembled Mira application, ready to serve.
|
|
26
44
|
*
|
|
@@ -69,7 +87,7 @@ export class MiraApp {
|
|
|
69
87
|
* collection definitions.
|
|
70
88
|
*
|
|
71
89
|
* @param plugin - A MiraPlugin (use `fromLayer()` to wrap a plain Layer)
|
|
72
|
-
* @returns this
|
|
90
|
+
* @returns this (for chaining)
|
|
73
91
|
*
|
|
74
92
|
* @example
|
|
75
93
|
* app.extend(MiraDashboard).serve()
|
|
@@ -79,8 +97,9 @@ export class MiraApp {
|
|
|
79
97
|
return this;
|
|
80
98
|
}
|
|
81
99
|
#getAllCollections() {
|
|
100
|
+
const configCollections = applyRulesToCollections(this.#config.collections, this.#config.rules ?? []);
|
|
82
101
|
return [
|
|
83
|
-
...
|
|
102
|
+
...configCollections,
|
|
84
103
|
...this.#extras.flatMap((p) => p.collections ?? [])
|
|
85
104
|
];
|
|
86
105
|
}
|
|
@@ -107,7 +126,7 @@ export class MiraApp {
|
|
|
107
126
|
* )
|
|
108
127
|
*/
|
|
109
128
|
buildServiceLayer() {
|
|
110
|
-
const {
|
|
129
|
+
const { database, platform, storage, telemetry } = this.#config;
|
|
111
130
|
const allCollections = this.#getAllCollections();
|
|
112
131
|
const allPlugins = this.#getAllPlugins();
|
|
113
132
|
const allCronDefs = this.#getAllCrons();
|
|
@@ -143,29 +162,26 @@ export class MiraApp {
|
|
|
143
162
|
* Build the complete server layer including the HTTP router and server.
|
|
144
163
|
* Accepts an optional port override (otherwise uses the port from AppConfig).
|
|
145
164
|
*
|
|
146
|
-
* @param options
|
|
165
|
+
* @param options - Optional serve options (`port`, `maxPortAttempts`)
|
|
147
166
|
* @returns A Layer ready to be launched
|
|
148
167
|
*
|
|
149
168
|
* @internal Called by serve() — most users should use serve() directly.
|
|
150
169
|
*/
|
|
151
170
|
buildLayer(options) {
|
|
152
171
|
const allCollections = this.#getAllCollections();
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
for (const plugin of this.#extras) {
|
|
157
|
-
if (plugin.routes !== undefined) {
|
|
158
|
-
pluginRouter = HttpRouter.concat(pluginRouter, plugin.routes);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
const router = HttpRouter.concat(collectionRouter, pluginRouter);
|
|
172
|
+
const collectionRoutes = makeCollectionRouter(allCollections);
|
|
173
|
+
const pluginRoutes = this.#extras.flatMap((p) => p.routes ?? []);
|
|
174
|
+
const routes = [...collectionRoutes, ...pluginRoutes];
|
|
162
175
|
const serviceLayer = this.buildServiceLayer();
|
|
163
|
-
const serverLayer = Layer.
|
|
176
|
+
const serverLayer = Layer.unwrap(Effect.gen(function* () {
|
|
164
177
|
const cfg = yield* AppConfig;
|
|
165
178
|
const factory = yield* HttpServerFactory;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
179
|
+
const effectivePort = options?.port ?? cfg.port;
|
|
180
|
+
return makePortRetryServerLayer(factory, effectivePort, options?.maxPortAttempts, (boundPort) => cfg.updateBoundPort?.(boundPort));
|
|
181
|
+
})).pipe(Layer.provide(serviceLayer));
|
|
182
|
+
return HttpRouter.serve(HttpRouter.addAll(routes), {
|
|
183
|
+
middleware: (effect) => ipAnnotationMiddleware(effect)
|
|
184
|
+
}).pipe(Layer.provide(serverLayer), Layer.provideMerge(serviceLayer));
|
|
169
185
|
}
|
|
170
186
|
/**
|
|
171
187
|
* Start the Mira HTTP server.
|
|
@@ -173,17 +189,21 @@ export class MiraApp {
|
|
|
173
189
|
* and listens for incoming requests.
|
|
174
190
|
* Blocks the main thread until the server is shut down.
|
|
175
191
|
*
|
|
176
|
-
*
|
|
192
|
+
* If the requested port is already in use, the server automatically retries
|
|
193
|
+
* on the next available port (up to `maxPortAttempts`, default 10).
|
|
194
|
+
*
|
|
195
|
+
* @param options - Optional serve options (`port`, `maxPortAttempts`)
|
|
177
196
|
*
|
|
178
197
|
* @example
|
|
179
|
-
* app.serve()
|
|
180
|
-
* app.serve({ port: 8080 })
|
|
198
|
+
* app.serve() // default port, auto-increment if busy
|
|
199
|
+
* app.serve({ port: 8080 }) // explicit port, auto-increment if busy
|
|
200
|
+
* app.serve({ port: 8080, maxPortAttempts: 1 }) // fail instead of incrementing
|
|
181
201
|
*/
|
|
182
202
|
serve(options) {
|
|
183
203
|
const allPlugins = this.#getAllPlugins();
|
|
184
204
|
const hookServiceLayer = makeHookServiceLayer(allPlugins);
|
|
185
205
|
const fullLayer = this.buildLayer(options);
|
|
186
|
-
this.#config.platform.runMain(Effect.gen(
|
|
206
|
+
this.#config.platform.runMain(Effect.gen(function* () {
|
|
187
207
|
const hookService = yield* HookService.pipe(Effect.provide(hookServiceLayer));
|
|
188
208
|
const bootstrapLayer = Layer.effectDiscard(hookService.runBootstrap());
|
|
189
209
|
yield* Layer.launch(bootstrapLayer.pipe(Layer.provideMerge(fullLayer)));
|
package/dist/src/app/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/app/app.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/app/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { Layer } from "effect";
|
|
2
1
|
import type { AnyCollectionDef } from "@gettersethya/mira-client";
|
|
2
|
+
import type { Layer } from "effect";
|
|
3
3
|
import type { CronDef } from "../cron/types.js";
|
|
4
|
-
import type { MiraPlatform, MiraDatabase, MiraStorage } from "./types.js";
|
|
5
4
|
import { MiraApp } from "./app.js";
|
|
5
|
+
import type { RuleBinding } from "./define-rule.js";
|
|
6
|
+
import type { MiraDatabase, MiraPlatform, MiraStorage, PlatformServices } from "./types.js";
|
|
6
7
|
/**
|
|
7
8
|
* Configuration object for `MiraApp`. Constructed by `MiraBuilder` after all
|
|
8
9
|
* required steps are called. Only the `telemetry` field is optional — it defaults
|
|
@@ -15,8 +16,9 @@ export interface MiraAppConfig {
|
|
|
15
16
|
database: MiraDatabase;
|
|
16
17
|
storage: MiraStorage;
|
|
17
18
|
collections: ReadonlyArray<AnyCollectionDef>;
|
|
19
|
+
rules?: ReadonlyArray<RuleBinding>;
|
|
18
20
|
crons: ReadonlyArray<CronDef<any>>;
|
|
19
|
-
telemetry: Layer.Layer<never, never,
|
|
21
|
+
telemetry: Layer.Layer<never, never, PlatformServices>;
|
|
20
22
|
}
|
|
21
23
|
/**
|
|
22
24
|
* Phantom-type builder for constructing a `MiraApp`.
|
|
@@ -77,13 +79,22 @@ export declare class MiraBuilder<Has extends string = never, R = never> {
|
|
|
77
79
|
storage(s: MiraStorage): MiraBuilder<Has | "storage", R>;
|
|
78
80
|
/**
|
|
79
81
|
* Set the collection definitions.
|
|
80
|
-
* Required step. The collections define the schema
|
|
82
|
+
* Required step. The collections define the schema for all entities.
|
|
81
83
|
*
|
|
82
84
|
* @param c - Array of collection definitions from BaseCollection.define(), AuthCollection.define(),
|
|
83
85
|
* or ViewCollection.define()
|
|
84
86
|
* @returns A new builder with "collections" added to the phantom type
|
|
85
87
|
*/
|
|
86
88
|
collections(c: ReadonlyArray<AnyCollectionDef>): MiraBuilder<Has | "collections", R>;
|
|
89
|
+
/**
|
|
90
|
+
* Set rule bindings for collections (optional).
|
|
91
|
+
* Rules are defined server-only via `Mira.defineRule()` and are merged onto
|
|
92
|
+
* collection schemas at build time. Collections without rules deny all actions.
|
|
93
|
+
*
|
|
94
|
+
* @param r - Array of RuleBinding from Mira.defineRule(collection, cb)
|
|
95
|
+
* @returns A new builder (same phantom type — rules is optional)
|
|
96
|
+
*/
|
|
97
|
+
rules(r: ReadonlyArray<RuleBinding>): MiraBuilder<Has, R>;
|
|
87
98
|
/**
|
|
88
99
|
* Set cron job definitions (optional).
|
|
89
100
|
* Crons are started as scoped fibers on boot and run on their schedule until the server stops.
|
|
@@ -94,12 +105,13 @@ export declare class MiraBuilder<Has extends string = never, R = never> {
|
|
|
94
105
|
crons<R2>(c: ReadonlyArray<CronDef<R2>>): MiraBuilder<Has, R | R2>;
|
|
95
106
|
/**
|
|
96
107
|
* Set a custom telemetry layer (optional).
|
|
97
|
-
* Defaults to `ConsoleTelemetryLayer` (prints JSON trace lines to stdout)
|
|
108
|
+
* Defaults to `ConsoleTelemetryLayer` (prints JSON trace lines to stdout),
|
|
109
|
+
* or `makeConsoleTelemetryLayer({ pretty: true })` for Chalk-colored output.
|
|
98
110
|
*
|
|
99
|
-
* @param l - A Layer providing telemetry services
|
|
111
|
+
* @param l - A Layer providing telemetry services (may require platform services)
|
|
100
112
|
* @returns A new builder with "telemetry" added to the phantom type
|
|
101
113
|
*/
|
|
102
|
-
telemetry(l: Layer.Layer<never, never,
|
|
114
|
+
telemetry(l: Layer.Layer<never, never, PlatformServices>): MiraBuilder<Has | "telemetry", R>;
|
|
103
115
|
/**
|
|
104
116
|
* Build the MiraApp from the accumulated configuration.
|
|
105
117
|
* Only compiles when all required steps (platform, database, storage, collections)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/app/builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/app/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAEnC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAG9C,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAE3F;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,YAAY,CAAA;IACtB,QAAQ,EAAE,YAAY,CAAA;IACtB,OAAO,EAAE,WAAW,CAAA;IACpB,WAAW,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;IAC5C,KAAK,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;IAClC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;IAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAA;CACvD;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,WAAW,CAAC,GAAG,SAAS,MAAM,GAAG,KAAK,EAAE,CAAC,GAAG,KAAK;;gBAGhD,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM;IAI/C,+BAA+B;IAC/B,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC;IAK3C;;;;;;;OAOG;IACH,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG,GAAG,UAAU,EAAE,CAAC,CAAC;IAI3D;;;;;;OAMG;IACH,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG,GAAG,UAAU,EAAE,CAAC,CAAC;IAI3D;;;;;;OAMG;IACH,OAAO,CAAC,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC,GAAG,GAAG,SAAS,EAAE,CAAC,CAAC;IAIxD;;;;;;;OAOG;IACH,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,WAAW,CAAC,GAAG,GAAG,aAAa,EAAE,CAAC,CAAC;IAIpF;;;;;;;OAOG;IACH,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC;IAWzD;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;IAIlE;;;;;;;OAOG;IACH,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,gBAAgB,CAAC,GAAG,WAAW,CAAC,GAAG,GAAG,WAAW,EAAE,CAAC,CAAC;IAI5F;;;;;;;;;;OAUG;IACH,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAe7F"}
|
package/dist/src/app/builder.js
CHANGED
|
@@ -75,7 +75,7 @@ export class MiraBuilder {
|
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
* Set the collection definitions.
|
|
78
|
-
* Required step. The collections define the schema
|
|
78
|
+
* Required step. The collections define the schema for all entities.
|
|
79
79
|
*
|
|
80
80
|
* @param c - Array of collection definitions from BaseCollection.define(), AuthCollection.define(),
|
|
81
81
|
* or ViewCollection.define()
|
|
@@ -84,6 +84,24 @@ export class MiraBuilder {
|
|
|
84
84
|
collections(c) {
|
|
85
85
|
return new MiraBuilder({ ...this.#config, collections: c });
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Set rule bindings for collections (optional).
|
|
89
|
+
* Rules are defined server-only via `Mira.defineRule()` and are merged onto
|
|
90
|
+
* collection schemas at build time. Collections without rules deny all actions.
|
|
91
|
+
*
|
|
92
|
+
* @param r - Array of RuleBinding from Mira.defineRule(collection, cb)
|
|
93
|
+
* @returns A new builder (same phantom type — rules is optional)
|
|
94
|
+
*/
|
|
95
|
+
rules(r) {
|
|
96
|
+
const seen = new Set();
|
|
97
|
+
for (const rb of r) {
|
|
98
|
+
if (seen.has(rb.collectionName)) {
|
|
99
|
+
throw new Error(`Duplicate rule binding for collection "${rb.collectionName}". Each collection may have at most one RuleBinding.`);
|
|
100
|
+
}
|
|
101
|
+
seen.add(rb.collectionName);
|
|
102
|
+
}
|
|
103
|
+
return new MiraBuilder({ ...this.#config, rules: r });
|
|
104
|
+
}
|
|
87
105
|
/**
|
|
88
106
|
* Set cron job definitions (optional).
|
|
89
107
|
* Crons are started as scoped fibers on boot and run on their schedule until the server stops.
|
|
@@ -96,9 +114,10 @@ export class MiraBuilder {
|
|
|
96
114
|
}
|
|
97
115
|
/**
|
|
98
116
|
* Set a custom telemetry layer (optional).
|
|
99
|
-
* Defaults to `ConsoleTelemetryLayer` (prints JSON trace lines to stdout)
|
|
117
|
+
* Defaults to `ConsoleTelemetryLayer` (prints JSON trace lines to stdout),
|
|
118
|
+
* or `makeConsoleTelemetryLayer({ pretty: true })` for Chalk-colored output.
|
|
100
119
|
*
|
|
101
|
-
* @param l - A Layer providing telemetry services
|
|
120
|
+
* @param l - A Layer providing telemetry services (may require platform services)
|
|
102
121
|
* @returns A new builder with "telemetry" added to the phantom type
|
|
103
122
|
*/
|
|
104
123
|
telemetry(l) {
|
|
@@ -125,6 +144,7 @@ export class MiraBuilder {
|
|
|
125
144
|
database: config.database,
|
|
126
145
|
storage: config.storage,
|
|
127
146
|
collections: config.collections,
|
|
147
|
+
rules: config.rules ?? [],
|
|
128
148
|
crons: config.crons ?? [],
|
|
129
149
|
telemetry: config.telemetry ?? ConsoleTelemetryLayer
|
|
130
150
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/app/builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/app/builder.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAqBlC,SAAS,eAAe,CAAC,MAA8B;IACrD,OAAO,CACL,MAAM,CAAC,QAAQ,KAAK,SAAS;QAC7B,MAAM,CAAC,QAAQ,KAAK,SAAS;QAC7B,MAAM,CAAC,OAAO,KAAK,SAAS;QAC5B,MAAM,CAAC,WAAW,KAAK,SAAS,CACjC,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,OAAO,WAAW;IACb,OAAO,CAAwB;IAExC,YAAY,SAAiC,EAAE;QAC7C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAED,+BAA+B;IAC/B,iBAAiB;QACf,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAGD;;;;;;;OAOG;IACH,QAAQ,CAAC,CAAe;QACtB,OAAO,IAAI,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAA;IAC1D,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,CAAe;QACtB,OAAO,IAAI,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAA;IAC1D,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,CAAc;QACpB,OAAO,IAAI,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAA;IACzD,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,CAAkC;QAC5C,OAAO,IAAI,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;IAC7D,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,CAA6B;QACjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,KAAK,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;YACnB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CAAC,0CAA0C,EAAE,CAAC,cAAc,sDAAsD,CAAC,CAAA;YACpI,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,cAAc,CAAC,CAAA;QAC7B,CAAC;QACD,OAAO,IAAI,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IACvD,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAK,CAA6B;QACrC,OAAO,IAAI,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IACvD,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,CAA8C;QACtD,OAAO,IAAI,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAA;IAC3D,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAA;QACvC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;QACzD,CAAC;QACD,OAAO,IAAI,OAAO,CAAI;YACpB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;YACzB,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,qBAAqB;SACrD,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { FieldDef, FieldsMap, RuleMap } from "@gettersethya/mira-client";
|
|
2
|
+
import type { FieldOperand, RuleBuilder } from "@gettersethya/mira-client";
|
|
3
|
+
type BaseSystemFieldDefs = {
|
|
4
|
+
id: FieldDef & {
|
|
5
|
+
kind: "text";
|
|
6
|
+
};
|
|
7
|
+
created: FieldDef & {
|
|
8
|
+
kind: "date";
|
|
9
|
+
};
|
|
10
|
+
updated: FieldDef & {
|
|
11
|
+
kind: "date";
|
|
12
|
+
};
|
|
13
|
+
seqId: FieldDef & {
|
|
14
|
+
kind: "seqId";
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
type AuthSystemFieldDefs = {
|
|
18
|
+
id: FieldDef & {
|
|
19
|
+
kind: "text";
|
|
20
|
+
};
|
|
21
|
+
email: FieldDef & {
|
|
22
|
+
kind: "email";
|
|
23
|
+
};
|
|
24
|
+
emailVerified: FieldDef & {
|
|
25
|
+
kind: "boolean";
|
|
26
|
+
};
|
|
27
|
+
created: FieldDef & {
|
|
28
|
+
kind: "date";
|
|
29
|
+
};
|
|
30
|
+
updated: FieldDef & {
|
|
31
|
+
kind: "date";
|
|
32
|
+
};
|
|
33
|
+
seqId: FieldDef & {
|
|
34
|
+
kind: "seqId";
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export interface RuleBinding {
|
|
38
|
+
readonly _tag: "RuleBinding";
|
|
39
|
+
readonly collectionName: string;
|
|
40
|
+
readonly ruleMap: RuleMap;
|
|
41
|
+
}
|
|
42
|
+
export type ViewRuleMap = {
|
|
43
|
+
list?: RuleMap["list"];
|
|
44
|
+
view?: RuleMap["view"];
|
|
45
|
+
};
|
|
46
|
+
export declare function defineRule<F extends FieldsMap>(collection: {
|
|
47
|
+
name: string;
|
|
48
|
+
fields: F;
|
|
49
|
+
schema: {
|
|
50
|
+
"x-collection-kind": "auth";
|
|
51
|
+
};
|
|
52
|
+
}, cb: (R: RuleBuilder<F & AuthSystemFieldDefs> & {
|
|
53
|
+
selfId(): FieldOperand<any, string>;
|
|
54
|
+
}) => RuleMap): RuleBinding;
|
|
55
|
+
export declare function defineRule<F extends FieldsMap>(collection: {
|
|
56
|
+
name: string;
|
|
57
|
+
fields: F;
|
|
58
|
+
schema: {
|
|
59
|
+
"x-collection-kind": "view";
|
|
60
|
+
};
|
|
61
|
+
}, cb: (R: RuleBuilder<F>) => ViewRuleMap): RuleBinding;
|
|
62
|
+
export declare function defineRule<F extends FieldsMap>(collection: {
|
|
63
|
+
name: string;
|
|
64
|
+
fields: F;
|
|
65
|
+
schema: {
|
|
66
|
+
"x-collection-kind": "base";
|
|
67
|
+
};
|
|
68
|
+
}, cb: (R: RuleBuilder<F & BaseSystemFieldDefs>) => RuleMap): RuleBinding;
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=define-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-rule.d.ts","sourceRoot":"","sources":["../../../src/app/define-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAC,SAAS,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAC,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAGzE,KAAK,mBAAmB,GAAG;IACzB,EAAE,EAAO,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,OAAO,EAAE,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,OAAO,EAAE,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,KAAK,EAAI,QAAQ,GAAG;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CACtC,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB,EAAE,EAAa,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,KAAK,EAAU,QAAQ,GAAG;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;IAC3C,aAAa,EAAE,QAAQ,GAAG;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAA;IAC7C,OAAO,EAAQ,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,OAAO,EAAQ,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,KAAK,EAAU,QAAQ,GAAG;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAC5C,CAAA;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;CACvB,CAAA;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAC5C,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE;QAAE,mBAAmB,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAChF,EAAE,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,GAAG,mBAAmB,CAAC,GAAG;IAAE,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;CAAE,KAAK,OAAO,GACjG,WAAW,CAAA;AAEd,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAC5C,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE;QAAE,mBAAmB,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAChF,EAAE,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,WAAW,GACrC,WAAW,CAAA;AAEd,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAC5C,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE;QAAE,mBAAmB,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAChF,EAAE,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,GAAG,mBAAmB,CAAC,KAAK,OAAO,GACvD,WAAW,CAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { makeRuleBuilder, toChainable } from "@gettersethya/mira-client";
|
|
2
|
+
export function defineRule(collection, cb) {
|
|
3
|
+
const kind = collection.schema["x-collection-kind"];
|
|
4
|
+
if (kind === "auth") {
|
|
5
|
+
const authBuilder = {
|
|
6
|
+
...makeRuleBuilder(),
|
|
7
|
+
selfId() {
|
|
8
|
+
return toChainable({ kind: "authId", collection: collection.name });
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const result = cb(authBuilder);
|
|
12
|
+
const ruleMap = {
|
|
13
|
+
...(result.list !== undefined ? { list: result.list } : {}),
|
|
14
|
+
...(result.view !== undefined ? { view: result.view } : {}),
|
|
15
|
+
...(result.create !== undefined ? { create: result.create } : {}),
|
|
16
|
+
...(result.update !== undefined ? { update: result.update } : {}),
|
|
17
|
+
...(result.delete !== undefined ? { delete: result.delete } : {}),
|
|
18
|
+
};
|
|
19
|
+
return { _tag: "RuleBinding", collectionName: collection.name, ruleMap };
|
|
20
|
+
}
|
|
21
|
+
if (kind === "view") {
|
|
22
|
+
const viewBuilder = makeRuleBuilder();
|
|
23
|
+
const result = cb(viewBuilder);
|
|
24
|
+
const ruleMap = {
|
|
25
|
+
...(result.list !== undefined ? { list: result.list } : {}),
|
|
26
|
+
...(result.view !== undefined ? { view: result.view } : {}),
|
|
27
|
+
};
|
|
28
|
+
return { _tag: "RuleBinding", collectionName: collection.name, ruleMap };
|
|
29
|
+
}
|
|
30
|
+
const baseBuilder = makeRuleBuilder();
|
|
31
|
+
const result = cb(baseBuilder);
|
|
32
|
+
const ruleMap = {
|
|
33
|
+
...(result.list !== undefined ? { list: result.list } : {}),
|
|
34
|
+
...(result.view !== undefined ? { view: result.view } : {}),
|
|
35
|
+
...(result.create !== undefined ? { create: result.create } : {}),
|
|
36
|
+
...(result.update !== undefined ? { update: result.update } : {}),
|
|
37
|
+
...(result.delete !== undefined ? { delete: result.delete } : {}),
|
|
38
|
+
};
|
|
39
|
+
return { _tag: "RuleBinding", collectionName: collection.name, ruleMap };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=define-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-rule.js","sourceRoot":"","sources":["../../../src/app/define-rule.ts"],"names":[],"mappings":"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"}
|