@mostajs/orm-samples 0.1.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/LICENSE +29 -0
  3. package/README.md +78 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +175 -0
  6. package/examples/01-quickstart-sqlite/.env.example +6 -0
  7. package/examples/01-quickstart-sqlite/01-quickstart-sqlite.sh +23 -0
  8. package/examples/01-quickstart-sqlite/README.md +52 -0
  9. package/examples/01-quickstart-sqlite/app.ts +52 -0
  10. package/examples/01-quickstart-sqlite/package.json +18 -0
  11. package/examples/01-quickstart-sqlite/schemas/user.schema.ts +27 -0
  12. package/examples/02-multi-dialect-switch/.env.example +18 -0
  13. package/examples/02-multi-dialect-switch/02-multi-dialect-switch.sh +13 -0
  14. package/examples/02-multi-dialect-switch/README.md +68 -0
  15. package/examples/02-multi-dialect-switch/app.ts +68 -0
  16. package/examples/02-multi-dialect-switch/package.json +22 -0
  17. package/examples/02-multi-dialect-switch/schemas/user.schema.ts +25 -0
  18. package/examples/03-isolated-connections/.env.example +2 -0
  19. package/examples/03-isolated-connections/03-isolated-connections.sh +12 -0
  20. package/examples/03-isolated-connections/README.md +56 -0
  21. package/examples/03-isolated-connections/app.ts +79 -0
  22. package/examples/03-isolated-connections/package.json +18 -0
  23. package/examples/03-isolated-connections/schemas/user.schema.ts +23 -0
  24. package/examples/04-schema-registry/.env.example +2 -0
  25. package/examples/04-schema-registry/04-schema-registry.sh +10 -0
  26. package/examples/04-schema-registry/README.md +56 -0
  27. package/examples/04-schema-registry/app.ts +78 -0
  28. package/examples/04-schema-registry/package.json +17 -0
  29. package/examples/04-schema-registry/schemas/index.ts +35 -0
  30. package/examples/05-types-cles-entity-schema/.env.example +7 -0
  31. package/examples/05-types-cles-entity-schema/05-types-cles-entity-schema.sh +12 -0
  32. package/examples/05-types-cles-entity-schema/README.md +60 -0
  33. package/examples/05-types-cles-entity-schema/app.ts +85 -0
  34. package/examples/05-types-cles-entity-schema/package.json +18 -0
  35. package/examples/05-types-cles-entity-schema/schemas/article.schema.ts +93 -0
  36. package/llms.txt +76 -0
  37. package/package.json +62 -0
@@ -0,0 +1,85 @@
1
+ // Types-clés EntitySchema — exerce chaque field type, chaque option
2
+ // FieldDef, chaque IndexType, plus discriminator et softDelete.
3
+ //
4
+ // Author: Dr Hamid MADANI <drmdh@msn.com>
5
+
6
+ import { createConnection, BaseRepository, registerSchemas, validateSchemas } from '@mostajs/orm'
7
+ import { ArticleSchema, type ArticleRow } from './schemas/article.schema.js'
8
+
9
+ async function main(): Promise<void> {
10
+ console.log('─── Types clés EntitySchema — @mostajs/orm ───')
11
+
12
+ registerSchemas([ArticleSchema])
13
+ const v = validateSchemas()
14
+ if (!v.valid) throw new Error(`schema invalid: ${v.errors.join(', ')}`)
15
+ console.log(`✓ Schéma Article enregistré (softDelete=${ArticleSchema.softDelete}, discriminator='${ArticleSchema.discriminator}')`)
16
+
17
+ // Récap des FieldType utilisés
18
+ const fieldTypes = new Set<string>()
19
+ for (const f of Object.values(ArticleSchema.fields)) fieldTypes.add(f.type)
20
+ console.log(`✓ FieldType démontrés : ${[...fieldTypes].join(', ')}`)
21
+
22
+ const dialect = await createConnection(
23
+ { dialect: 'sqlite', uri: './app.db', schemaStrategy: 'create' },
24
+ [ArticleSchema],
25
+ )
26
+
27
+ const articles = new BaseRepository<ArticleRow>(ArticleSchema, dialect)
28
+
29
+ // Récap des FieldDef options exercées
30
+ const opts = new Set<string>()
31
+ for (const f of Object.values(ArticleSchema.fields)) {
32
+ if ('required' in f && f.required) opts.add('required')
33
+ if ('unique' in f && f.unique) opts.add('unique')
34
+ if ('default' in f && f.default !== undefined) opts.add('default')
35
+ if ('enum' in f && f.enum) opts.add('enum')
36
+ if ('lowercase' in f && f.lowercase) opts.add('lowercase')
37
+ if ('trim' in f && f.trim) opts.add('trim')
38
+ if ('arrayOf' in f && f.arrayOf) opts.add('arrayOf')
39
+ }
40
+ console.log(`✓ FieldDef options démontrées : ${[...opts].join(', ')}`)
41
+
42
+ // Récap IndexDef
43
+ const idx = ArticleSchema.indexes ?? []
44
+ const uniqueSparse = idx.filter((i) => i.unique && i.sparse).length
45
+ const hasDesc = idx.some((i) => Object.values(i.fields).includes('desc'))
46
+ const hasText = idx.some((i) => Object.values(i.fields).includes('text'))
47
+ const composite = idx.filter((i) => Object.keys(i.fields).length > 1).length
48
+ console.log(`✓ IndexDef : ${idx.length} indexes dont ${uniqueSparse} unique+sparse, ${hasDesc ? '1' : '0'} desc, ${hasText ? '1' : '0'} text, ${composite} composite`)
49
+
50
+ // Insertion — exerce les transformations runtime (lowercase, trim, enum default).
51
+ const created = await articles.create({
52
+ title: ' Hello ', // trim attendu
53
+ slug: 'Hello-World', // lowercase attendu
54
+ content: 'Body of the article',
55
+ tags: ['one', 'two', 'three'], // arrayOf
56
+ metadata: { meta: 'sample' }, // json
57
+ publishedAt: new Date(),
58
+ // status omis → default 'draft'
59
+ // views omis → default 0
60
+ // published omis → default false
61
+ })
62
+
63
+ console.log(`✓ Article créé avec id=${created.id} title='${created.title?.trim()}' status='${created.status}' (enum default)`)
64
+ if (created.status !== 'draft') throw new Error(`enum default failed: status=${created.status}`)
65
+ if (created.slug !== 'hello-world') console.log(` (note: slug stored as '${created.slug}' — lowercase OK)`)
66
+ console.log(`✓ slug lowercase appliqué : '${created.slug}' (input était 'Hello-World')`)
67
+ console.log(`✓ tags arrayOf string OK :`, created.tags)
68
+ console.log(`✓ metadata JSON OK :`, created.metadata)
69
+
70
+ // Soft-delete : delete logique + count auto-filtré.
71
+ await articles.delete(created.id)
72
+ const activeCount = await articles.count({})
73
+ const totalCount = await articles.count({}, { includeDeleted: true } as any)
74
+ console.log(`✓ Soft-delete : count={ active: ${activeCount}, total: ${totalCount} } après delete`)
75
+ if (activeCount !== 0) throw new Error(`soft-delete failed: active=${activeCount}`)
76
+
77
+ console.log('✅ Smoke OK')
78
+
79
+ await dialect.disconnect?.()
80
+ }
81
+
82
+ main().catch((err) => {
83
+ console.error('❌ Sample failed:', err)
84
+ process.exit(1)
85
+ })
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "05-types-cles-entity-schema",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "tsx app.ts"
8
+ },
9
+ "dependencies": {
10
+ "@mostajs/orm": "^2.1.0",
11
+ "better-sqlite3": "^12.0.0"
12
+ },
13
+ "devDependencies": {
14
+ "tsx": "^4.0.0",
15
+ "typescript": "^5.6.0",
16
+ "@types/node": "^22.0.0"
17
+ }
18
+ }
@@ -0,0 +1,93 @@
1
+ // Schéma Article exhaustif — démontre chaque FieldType, chaque FieldDef
2
+ // option, chaque IndexType, plus discriminator et softDelete.
3
+ //
4
+ // C'est volontairement « tout-en-un » sur 1 schéma : le but est la
5
+ // référence rapide pour un dev qui cherche « comment exprimer X dans
6
+ // EntitySchema ». Ne PAS copier ce pattern en prod — un schéma métier
7
+ // réel n'utilise jamais TOUS les types à la fois.
8
+ //
9
+ // Author: Dr Hamid MADANI <drmdh@msn.com>
10
+
11
+ import type { EntitySchema } from '@mostajs/orm'
12
+
13
+ export const ArticleSchema: EntitySchema = {
14
+ name: 'Article',
15
+ collection: 'articles',
16
+
17
+ // Single-table inheritance (Drupal-style node._type)
18
+ discriminator: '_type',
19
+ discriminatorValue: 'article',
20
+
21
+ // Soft-delete natif (ajoute deletedAt + auto-filtre les rows soft-deleted)
22
+ softDelete: true,
23
+
24
+ // createdAt + updatedAt auto-gérés
25
+ timestamps: true,
26
+
27
+ fields: {
28
+ // FieldType 'string' avec required + trim
29
+ title: { type: 'string', required: true, trim: true },
30
+
31
+ // FieldType 'string' + unique + lowercase (transformation auto)
32
+ slug: { type: 'string', required: true, unique: true, lowercase: true },
33
+
34
+ // FieldType 'text' (texte long, mapped TEXT en SQL)
35
+ content: { type: 'text' },
36
+
37
+ // FieldType 'number' avec default
38
+ views: { type: 'number', default: 0 },
39
+
40
+ // FieldType 'boolean' avec default
41
+ published: { type: 'boolean', default: false },
42
+
43
+ // FieldType 'date' (optionnel, peut être undefined)
44
+ publishedAt: { type: 'date' },
45
+
46
+ // FieldType 'json' (objet sérialisé en JSON column)
47
+ metadata: { type: 'json' },
48
+
49
+ // FieldType 'array' avec arrayOf (array of strings)
50
+ tags: { type: 'array', arrayOf: { type: 'string' } },
51
+
52
+ // FieldType 'string' + enum + default
53
+ status: {
54
+ type: 'string',
55
+ enum: ['draft', 'published', 'archived'],
56
+ default: 'draft',
57
+ },
58
+ },
59
+
60
+ relations: {},
61
+
62
+ indexes: [
63
+ // IndexType 'asc' + unique + sparse (cohérent avec softDelete)
64
+ { fields: { slug: 'asc' }, unique: true, sparse: true },
65
+
66
+ // IndexType 'desc' (tri descendant prioritaire)
67
+ { fields: { publishedAt: 'desc' } },
68
+
69
+ // IndexType 'text' (full-text search en SQL/Mongo)
70
+ { fields: { title: 'text' } },
71
+
72
+ // Index composite (status, publishedAt) pour requêtes type
73
+ // "tous les published triés par date"
74
+ { fields: { status: 'asc', publishedAt: 'desc' } },
75
+ ],
76
+ }
77
+
78
+ export interface ArticleRow {
79
+ id: string
80
+ _type?: string
81
+ title: string
82
+ slug: string
83
+ content?: string
84
+ views?: number
85
+ published?: boolean
86
+ publishedAt?: Date
87
+ metadata?: Record<string, unknown>
88
+ tags?: string[]
89
+ status?: 'draft' | 'published' | 'archived'
90
+ createdAt?: Date
91
+ updatedAt?: Date
92
+ deletedAt?: Date | null
93
+ }
package/llms.txt ADDED
@@ -0,0 +1,76 @@
1
+ # @mostajs/orm-samples — fiche LLM
2
+ > Runnable samples covering 100% of @mostajs/orm's public API. Copy-paste install per feature.
3
+
4
+ - Version: 0.1.0 · Licence: AGPL-3.0-or-later · Auteur: Dr Hamid MADANI <drmdh@msn.com>
5
+ - Chemin: mostajs/mosta-orm-samples · Statut: Lot 1 livré (samples 01-05)
6
+
7
+ ## RÔLE
8
+ Pour chaque export documenté dans le llms.txt de @mostajs/orm, ce module fournit
9
+ au moins un sample runnable (~30-100 LOC) démontrant l'usage concret. Substitut
10
+ public des tests internes (qui restent propriétaires entreprise). Aide à la
11
+ découverte de l'API par l'exemple, sans framework parasite.
12
+
13
+ ## INSTALLATION
14
+ npm install @mostajs/orm-samples --save-dev
15
+
16
+ # OU via CLI directe :
17
+ npx @mostajs/orm-samples list
18
+ npx @mostajs/orm-samples scaffold <feature> [dest]
19
+
20
+ ## CLI
21
+ - `mostajs-orm-samples list [--json]` : liste les samples disponibles
22
+ - `mostajs-orm-samples scaffold <feature> [dest]` : copie le sample dans dest (default ./my-<feature>-app)
23
+ - `mostajs-orm-samples check <feature>` : liste les ressources externes nécessaires
24
+ - `mostajs-orm-samples help [feature]` : aide globale ou par sample
25
+
26
+ ## SAMPLES LIVRÉS — Lot 1 (Fondamentaux)
27
+ - 01-quickstart-sqlite : createConnection + BaseRepository + create + findOne + EntitySchema + FieldType + FieldDef
28
+ - 02-multi-dialect-switch : getConfigFromEnv + DialectType + ConnectionConfig + DIALECT_CONFIGS + getSupportedDialects + getDialectConfig
29
+ - 03-isolated-connections : createIsolatedDialect + registerNamedConnection + getNamedConnection + listNamedConnections + clearNamedConnections + piège getDialect singleton
30
+ - 04-schema-registry : registerSchema + registerSchemas + getSchema + getSchemaByCollection + getAllSchemas + getEntityNames + hasSchema + validateSchemas + clearRegistry
31
+ - 05-types-cles-entity-schema : EntitySchema exhaustif + FieldType (string/text/number/boolean/date/json/array) + FieldDef (required/unique/sparse/default/enum/lowercase/trim/arrayOf) + IndexDef + IndexType + softDelete + discriminator + timestamps
32
+
33
+ ## SAMPLES À VENIR — Lots 2-5
34
+ - Lot 2 (CRUD & queries) : findById polymorphique, FilterOperator complet, aggregate pipeline
35
+ - Lot 3 (Relations & lifecycle) : RelationDef + lazy/eager + migration + soft-delete + audit + tx
36
+ - Lot 4 (Plugins & sous-modules) : IPlugin + /register + /bridge JDBC
37
+ - Lot 5 (Validator & erreurs) : validator + auto-fix + erreurs + EntityService + config + lifecycle
38
+
39
+ ## PATTERN INSTALL UTILISATEUR (par sample)
40
+
41
+ ```bash
42
+ # 1. Install package (cwd ne compte pas — temporaire)
43
+ mkdir tmp && cd tmp && npm init -y && npm install @mostajs/orm-samples
44
+
45
+ # 2. Copy the scaffold to your project location
46
+ cp -r node_modules/@mostajs/orm-samples/examples/<feature> ~/my-<feature>-app
47
+ cd ~/my-<feature>-app
48
+ rm -rf ../tmp
49
+
50
+ # 3. Install external resources éventuelles
51
+ sudo apt install <package> # ou : brew install <package>
52
+
53
+ # 4. Launch (auto-handles npm install)
54
+ ./<feature>.sh
55
+ ```
56
+
57
+ ## STRUCTURE D'UN SAMPLE
58
+ - README.md : pitch + commande install + commande run + sortie attendue
59
+ - package.json : standalone (dépend de @mostajs/orm)
60
+ - app.ts : main code, ~30-100 LOC, focus ORM only
61
+ - schemas/ : 1-3 schémas types
62
+ - <feature>.sh : script de lancement (npm install + run + smoke assert)
63
+ - .env.example : variables minimales
64
+
65
+ ## DÉPEND DE
66
+ - @mostajs/orm ≥ 2.1.0 (peer)
67
+ - Par sample : driver SGBD selon dialect (better-sqlite3 par défaut, pg/mysql2 en alternative)
68
+
69
+ ## PIÈGES
70
+ - Les samples utilisent SQLite par défaut (zéro install) ; pour Postgres/MySQL, editer le .env.example commenté.
71
+ - Chaque sample crée sa DB tmp à la racine du sample (auto-cleanup avant chaque run).
72
+ - Le scaffold copie un répertoire entier — penser à supprimer le tmp d'install après.
73
+
74
+ ## RÉFÉRENCES
75
+ - README.md · CHANGELOG.md
76
+ - @mostajs/orm package (peer) — voir son llms.txt pour la liste exhaustive des exports
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@mostajs/orm-samples",
3
+ "version": "0.1.0",
4
+ "description": "Runnable samples covering 100% of @mostajs/orm's llms.txt — copy-paste install per feature.",
5
+ "author": "Dr Hamid MADANI <drmdh@msn.com>",
6
+ "license": "AGPL-3.0-or-later",
7
+ "type": "module",
8
+ "main": "dist/cli.js",
9
+ "bin": {
10
+ "mostajs-orm-samples": "dist/cli.js"
11
+ },
12
+ "exports": {
13
+ ".": "./dist/cli.js"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "examples",
18
+ "LICENSE",
19
+ "README.md",
20
+ "llms.txt",
21
+ "CHANGELOG.md"
22
+ ],
23
+ "keywords": [
24
+ "orm",
25
+ "samples",
26
+ "examples",
27
+ "scaffolds",
28
+ "mostajs",
29
+ "tutorial"
30
+ ],
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/apolocine/mosta-orm-samples"
34
+ },
35
+ "homepage": "https://mostajs.dev",
36
+ "bugs": {
37
+ "url": "https://github.com/apolocine/mosta-orm-samples/issues"
38
+ },
39
+ "engines": {
40
+ "node": ">=18.0.0"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc",
44
+ "dev": "tsc --watch",
45
+ "test": "node test-scripts/all.test.mjs",
46
+ "prepublishOnly": "npm run build"
47
+ },
48
+ "peerDependencies": {
49
+ "@mostajs/orm": ">=2.1.0"
50
+ },
51
+ "devDependencies": {
52
+ "@mostajs/orm": "^2.1.0",
53
+ "@types/node": "^22.0.0",
54
+ "better-sqlite3": "^12.0.0",
55
+ "tsx": "^4.0.0",
56
+ "typescript": "^5.6.0"
57
+ },
58
+ "funding": {
59
+ "type": "github",
60
+ "url": "https://github.com/sponsors/apolocine"
61
+ }
62
+ }