archetype-engine 2.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.
Files changed (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -0
  3. package/dist/src/ai/adapters/anthropic.d.ts +31 -0
  4. package/dist/src/ai/adapters/anthropic.d.ts.map +1 -0
  5. package/dist/src/ai/adapters/anthropic.js +75 -0
  6. package/dist/src/ai/adapters/openai.d.ts +33 -0
  7. package/dist/src/ai/adapters/openai.d.ts.map +1 -0
  8. package/dist/src/ai/adapters/openai.js +120 -0
  9. package/dist/src/ai/adapters/vercel.d.ts +434 -0
  10. package/dist/src/ai/adapters/vercel.d.ts.map +1 -0
  11. package/dist/src/ai/adapters/vercel.js +162 -0
  12. package/dist/src/ai/index.d.ts +492 -0
  13. package/dist/src/ai/index.d.ts.map +1 -0
  14. package/dist/src/ai/index.js +71 -0
  15. package/dist/src/ai/state.d.ts +13 -0
  16. package/dist/src/ai/state.d.ts.map +1 -0
  17. package/dist/src/ai/state.js +215 -0
  18. package/dist/src/ai/tools.d.ts +13 -0
  19. package/dist/src/ai/tools.d.ts.map +1 -0
  20. package/dist/src/ai/tools.js +257 -0
  21. package/dist/src/ai/types.d.ts +196 -0
  22. package/dist/src/ai/types.d.ts.map +1 -0
  23. package/dist/src/ai/types.js +9 -0
  24. package/dist/src/cli.d.ts +3 -0
  25. package/dist/src/cli.d.ts.map +1 -0
  26. package/dist/src/cli.js +540 -0
  27. package/dist/src/core/utils.d.ts +27 -0
  28. package/dist/src/core/utils.d.ts.map +1 -0
  29. package/dist/src/core/utils.js +56 -0
  30. package/dist/src/entity.d.ts +165 -0
  31. package/dist/src/entity.d.ts.map +1 -0
  32. package/dist/src/entity.js +108 -0
  33. package/dist/src/fields.d.ts +207 -0
  34. package/dist/src/fields.d.ts.map +1 -0
  35. package/dist/src/fields.js +291 -0
  36. package/dist/src/generators/erd-ir.d.ts +10 -0
  37. package/dist/src/generators/erd-ir.d.ts.map +1 -0
  38. package/dist/src/generators/erd-ir.js +119 -0
  39. package/dist/src/index.d.ts +51 -0
  40. package/dist/src/index.d.ts.map +1 -0
  41. package/dist/src/index.js +101 -0
  42. package/dist/src/init/dependencies.d.ts +31 -0
  43. package/dist/src/init/dependencies.d.ts.map +1 -0
  44. package/dist/src/init/dependencies.js +101 -0
  45. package/dist/src/init/entity-templates.d.ts +42 -0
  46. package/dist/src/init/entity-templates.d.ts.map +1 -0
  47. package/dist/src/init/entity-templates.js +367 -0
  48. package/dist/src/init/index.d.ts +10 -0
  49. package/dist/src/init/index.d.ts.map +1 -0
  50. package/dist/src/init/index.js +250 -0
  51. package/dist/src/init/prompts.d.ts +11 -0
  52. package/dist/src/init/prompts.d.ts.map +1 -0
  53. package/dist/src/init/prompts.js +275 -0
  54. package/dist/src/init/templates.d.ts +24 -0
  55. package/dist/src/init/templates.d.ts.map +1 -0
  56. package/dist/src/init/templates.js +587 -0
  57. package/dist/src/json/index.d.ts +11 -0
  58. package/dist/src/json/index.d.ts.map +1 -0
  59. package/dist/src/json/index.js +26 -0
  60. package/dist/src/json/parser.d.ts +61 -0
  61. package/dist/src/json/parser.d.ts.map +1 -0
  62. package/dist/src/json/parser.js +309 -0
  63. package/dist/src/json/types.d.ts +275 -0
  64. package/dist/src/json/types.d.ts.map +1 -0
  65. package/dist/src/json/types.js +10 -0
  66. package/dist/src/manifest.d.ts +147 -0
  67. package/dist/src/manifest.d.ts.map +1 -0
  68. package/dist/src/manifest.js +104 -0
  69. package/dist/src/relations.d.ts +96 -0
  70. package/dist/src/relations.d.ts.map +1 -0
  71. package/dist/src/relations.js +108 -0
  72. package/dist/src/source.d.ts +93 -0
  73. package/dist/src/source.d.ts.map +1 -0
  74. package/dist/src/source.js +89 -0
  75. package/dist/src/template/context.d.ts +34 -0
  76. package/dist/src/template/context.d.ts.map +1 -0
  77. package/dist/src/template/context.js +31 -0
  78. package/dist/src/template/index.d.ts +6 -0
  79. package/dist/src/template/index.d.ts.map +1 -0
  80. package/dist/src/template/index.js +12 -0
  81. package/dist/src/template/registry.d.ts +18 -0
  82. package/dist/src/template/registry.d.ts.map +1 -0
  83. package/dist/src/template/registry.js +89 -0
  84. package/dist/src/template/runner.d.ts +9 -0
  85. package/dist/src/template/runner.d.ts.map +1 -0
  86. package/dist/src/template/runner.js +125 -0
  87. package/dist/src/template/types.d.ts +73 -0
  88. package/dist/src/template/types.d.ts.map +1 -0
  89. package/dist/src/template/types.js +3 -0
  90. package/dist/src/templates/nextjs-drizzle-trpc/generators/api.d.ts +22 -0
  91. package/dist/src/templates/nextjs-drizzle-trpc/generators/api.d.ts.map +1 -0
  92. package/dist/src/templates/nextjs-drizzle-trpc/generators/api.js +866 -0
  93. package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.d.ts +20 -0
  94. package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.d.ts.map +1 -0
  95. package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.js +273 -0
  96. package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.d.ts +22 -0
  97. package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.d.ts.map +1 -0
  98. package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.js +237 -0
  99. package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.d.ts +30 -0
  100. package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.d.ts.map +1 -0
  101. package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.js +345 -0
  102. package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.d.ts +25 -0
  103. package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.d.ts.map +1 -0
  104. package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.js +199 -0
  105. package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts +8 -0
  106. package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts.map +1 -0
  107. package/dist/src/templates/nextjs-drizzle-trpc/generators/index.js +18 -0
  108. package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.d.ts +22 -0
  109. package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.d.ts.map +1 -0
  110. package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.js +270 -0
  111. package/dist/src/templates/nextjs-drizzle-trpc/generators/service.d.ts +23 -0
  112. package/dist/src/templates/nextjs-drizzle-trpc/generators/service.d.ts.map +1 -0
  113. package/dist/src/templates/nextjs-drizzle-trpc/generators/service.js +304 -0
  114. package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.d.ts +21 -0
  115. package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.d.ts.map +1 -0
  116. package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.js +248 -0
  117. package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts +30 -0
  118. package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts.map +1 -0
  119. package/dist/src/templates/nextjs-drizzle-trpc/index.js +71 -0
  120. package/dist/src/validation/index.d.ts +71 -0
  121. package/dist/src/validation/index.d.ts.map +1 -0
  122. package/dist/src/validation/index.js +314 -0
  123. package/package.json +86 -0
@@ -0,0 +1,314 @@
1
+ "use strict";
2
+ /**
3
+ * Validation Module for AI Agent Input
4
+ *
5
+ * Provides structured validation with error codes that AI agents can parse
6
+ * and use to fix their output.
7
+ *
8
+ * @module validation
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.ValidationCodes = void 0;
12
+ exports.validateManifest = validateManifest;
13
+ // Error codes
14
+ exports.ValidationCodes = {
15
+ // Entity errors
16
+ INVALID_ENTITY_NAME: 'INVALID_ENTITY_NAME',
17
+ DUPLICATE_ENTITY: 'DUPLICATE_ENTITY',
18
+ MISSING_ENTITY_FIELDS: 'MISSING_ENTITY_FIELDS',
19
+ // Field errors
20
+ INVALID_FIELD_TYPE: 'INVALID_FIELD_TYPE',
21
+ INVALID_FIELD_NAME: 'INVALID_FIELD_NAME',
22
+ // Relation errors
23
+ RELATION_TARGET_NOT_FOUND: 'RELATION_TARGET_NOT_FOUND',
24
+ INVALID_RELATION_TYPE: 'INVALID_RELATION_TYPE',
25
+ // Database errors
26
+ DATABASE_REQUIRED: 'DATABASE_REQUIRED',
27
+ INVALID_DATABASE_TYPE: 'INVALID_DATABASE_TYPE',
28
+ SQLITE_REQUIRES_FILE: 'SQLITE_REQUIRES_FILE',
29
+ POSTGRES_REQUIRES_URL: 'POSTGRES_REQUIRES_URL',
30
+ // Auth errors
31
+ AUTH_REQUIRED_FOR_PROTECTED: 'AUTH_REQUIRED_FOR_PROTECTED',
32
+ INVALID_PROVIDER: 'INVALID_PROVIDER',
33
+ // Mode errors
34
+ INVALID_MODE: 'INVALID_MODE',
35
+ // Protected errors
36
+ INVALID_PROTECTED_VALUE: 'INVALID_PROTECTED_VALUE',
37
+ // Source errors
38
+ EXTERNAL_SOURCE_INVALID: 'EXTERNAL_SOURCE_INVALID',
39
+ };
40
+ /**
41
+ * Check if a string is PascalCase
42
+ */
43
+ function isPascalCase(str) {
44
+ return /^[A-Z][a-zA-Z0-9]*$/.test(str);
45
+ }
46
+ /**
47
+ * Check if a string is camelCase
48
+ */
49
+ function isCamelCase(str) {
50
+ return /^[a-z][a-zA-Z0-9]*$/.test(str);
51
+ }
52
+ /**
53
+ * Validate a field definition
54
+ */
55
+ function validateField(fieldName, field, entityName) {
56
+ const errors = [];
57
+ const path = `${entityName}.fields.${fieldName}`;
58
+ // Check field name is camelCase
59
+ if (!isCamelCase(fieldName)) {
60
+ errors.push({
61
+ code: exports.ValidationCodes.INVALID_FIELD_NAME,
62
+ path,
63
+ message: `Field name '${fieldName}' must be camelCase`,
64
+ suggestion: `Rename to '${fieldName.charAt(0).toLowerCase()}${fieldName.slice(1)}'`,
65
+ });
66
+ }
67
+ // Check field type is valid
68
+ const validTypes = ['text', 'number', 'boolean', 'date'];
69
+ if (!validTypes.includes(field.type)) {
70
+ errors.push({
71
+ code: exports.ValidationCodes.INVALID_FIELD_TYPE,
72
+ path: `${path}.type`,
73
+ message: `Invalid field type '${field.type}'`,
74
+ suggestion: `Use one of: ${validTypes.join(', ')}`,
75
+ });
76
+ }
77
+ return errors;
78
+ }
79
+ /**
80
+ * Validate a relation definition
81
+ */
82
+ function validateRelation(relationName, relation, entityName, entityNames) {
83
+ const errors = [];
84
+ const path = `${entityName}.relations.${relationName}`;
85
+ // Check relation type is valid
86
+ const validTypes = ['hasOne', 'hasMany', 'belongsToMany'];
87
+ if (!validTypes.includes(relation.type)) {
88
+ errors.push({
89
+ code: exports.ValidationCodes.INVALID_RELATION_TYPE,
90
+ path: `${path}.type`,
91
+ message: `Invalid relation type '${relation.type}'`,
92
+ suggestion: `Use one of: ${validTypes.join(', ')}`,
93
+ });
94
+ }
95
+ // Check target entity exists
96
+ if (!entityNames.has(relation.entity)) {
97
+ errors.push({
98
+ code: exports.ValidationCodes.RELATION_TARGET_NOT_FOUND,
99
+ path: `${path}.entity`,
100
+ message: `Entity '${relation.entity}' not found in manifest`,
101
+ suggestion: `Add entity '${relation.entity}' to the entities array, or fix the entity name`,
102
+ });
103
+ }
104
+ return errors;
105
+ }
106
+ /**
107
+ * Validate an entity definition
108
+ */
109
+ function validateEntity(entity, entityNames, authEnabled) {
110
+ const errors = [];
111
+ const path = entity.name;
112
+ // Check entity name is PascalCase
113
+ if (!isPascalCase(entity.name)) {
114
+ errors.push({
115
+ code: exports.ValidationCodes.INVALID_ENTITY_NAME,
116
+ path,
117
+ message: `Entity name '${entity.name}' must be PascalCase`,
118
+ suggestion: `Rename to '${entity.name.charAt(0).toUpperCase()}${entity.name.slice(1)}'`,
119
+ });
120
+ }
121
+ // Check entity has fields
122
+ if (!entity.fields || Object.keys(entity.fields).length === 0) {
123
+ errors.push({
124
+ code: exports.ValidationCodes.MISSING_ENTITY_FIELDS,
125
+ path: `${path}.fields`,
126
+ message: `Entity '${entity.name}' must have at least one field`,
127
+ suggestion: `Add fields to the entity`,
128
+ });
129
+ }
130
+ // Validate fields
131
+ if (entity.fields) {
132
+ for (const [fieldName, field] of Object.entries(entity.fields)) {
133
+ errors.push(...validateField(fieldName, field, entity.name));
134
+ }
135
+ }
136
+ // Validate relations
137
+ if (entity.relations) {
138
+ for (const [relationName, relation] of Object.entries(entity.relations)) {
139
+ errors.push(...validateRelation(relationName, relation, entity.name, entityNames));
140
+ }
141
+ }
142
+ // Check protected requires auth
143
+ if (entity.protected !== undefined && entity.protected !== false) {
144
+ if (!authEnabled) {
145
+ errors.push({
146
+ code: exports.ValidationCodes.AUTH_REQUIRED_FOR_PROTECTED,
147
+ path: `${path}.protected`,
148
+ message: `Entity '${entity.name}' has protected operations but auth is not enabled`,
149
+ suggestion: `Add auth: { enabled: true } to manifest, or remove protected from entity`,
150
+ });
151
+ }
152
+ // Validate protected value
153
+ const validProtectedStrings = ['write', 'all'];
154
+ if (typeof entity.protected !== 'boolean' &&
155
+ typeof entity.protected !== 'object' &&
156
+ !validProtectedStrings.includes(entity.protected)) {
157
+ errors.push({
158
+ code: exports.ValidationCodes.INVALID_PROTECTED_VALUE,
159
+ path: `${path}.protected`,
160
+ message: `Invalid protected value '${entity.protected}'`,
161
+ suggestion: `Use one of: true, false, 'write', 'all', or an object with list/get/create/update/remove`,
162
+ });
163
+ }
164
+ }
165
+ // Validate external source
166
+ if (entity.source && !entity.source.baseUrl) {
167
+ errors.push({
168
+ code: exports.ValidationCodes.EXTERNAL_SOURCE_INVALID,
169
+ path: `${path}.source.baseUrl`,
170
+ message: `External source requires baseUrl`,
171
+ suggestion: `Add baseUrl to source, e.g., 'env:API_URL' or 'https://api.example.com'`,
172
+ });
173
+ }
174
+ return errors;
175
+ }
176
+ /**
177
+ * Validate database configuration
178
+ */
179
+ function validateDatabase(manifest) {
180
+ const errors = [];
181
+ const mode = manifest.mode || 'full';
182
+ // Full mode requires database
183
+ if (mode === 'full' && !manifest.database) {
184
+ errors.push({
185
+ code: exports.ValidationCodes.DATABASE_REQUIRED,
186
+ path: 'database',
187
+ message: `Mode 'full' requires database configuration`,
188
+ suggestion: `Add database config or use mode: 'headless'`,
189
+ });
190
+ return errors;
191
+ }
192
+ if (manifest.database) {
193
+ const db = manifest.database;
194
+ // Check database type
195
+ const validTypes = ['sqlite', 'postgres', 'mysql'];
196
+ if (!validTypes.includes(db.type)) {
197
+ errors.push({
198
+ code: exports.ValidationCodes.INVALID_DATABASE_TYPE,
199
+ path: 'database.type',
200
+ message: `Invalid database type '${db.type}'`,
201
+ suggestion: `Use one of: ${validTypes.join(', ')}`,
202
+ });
203
+ }
204
+ // SQLite requires file
205
+ if (db.type === 'sqlite' && !db.file) {
206
+ errors.push({
207
+ code: exports.ValidationCodes.SQLITE_REQUIRES_FILE,
208
+ path: 'database.file',
209
+ message: `SQLite database requires file path`,
210
+ suggestion: `Add file: './sqlite.db' to database config`,
211
+ });
212
+ }
213
+ // Postgres/MySQL requires url
214
+ if ((db.type === 'postgres' || db.type === 'mysql') && !db.url) {
215
+ errors.push({
216
+ code: exports.ValidationCodes.POSTGRES_REQUIRES_URL,
217
+ path: 'database.url',
218
+ message: `${db.type} database requires connection URL`,
219
+ suggestion: `Add url: 'env:DATABASE_URL' or a connection string`,
220
+ });
221
+ }
222
+ }
223
+ return errors;
224
+ }
225
+ /**
226
+ * Validate auth configuration
227
+ */
228
+ function validateAuth(manifest) {
229
+ const errors = [];
230
+ if (manifest.auth?.providers) {
231
+ const validProviders = ['credentials', 'google', 'github', 'discord'];
232
+ for (const provider of manifest.auth.providers) {
233
+ if (!validProviders.includes(provider)) {
234
+ errors.push({
235
+ code: exports.ValidationCodes.INVALID_PROVIDER,
236
+ path: 'auth.providers',
237
+ message: `Invalid auth provider '${provider}'`,
238
+ suggestion: `Use one of: ${validProviders.join(', ')}`,
239
+ });
240
+ }
241
+ }
242
+ }
243
+ return errors;
244
+ }
245
+ /**
246
+ * Validate a JSON manifest
247
+ *
248
+ * @param manifest - JSON manifest to validate
249
+ * @returns Validation result with errors and warnings
250
+ *
251
+ * @example
252
+ * ```typescript
253
+ * const result = validateManifest({
254
+ * entities: [{ name: 'User', fields: { email: { type: 'text' } } }],
255
+ * database: { type: 'sqlite', file: './app.db' }
256
+ * })
257
+ *
258
+ * if (!result.valid) {
259
+ * console.log('Errors:', result.errors)
260
+ * }
261
+ * ```
262
+ */
263
+ function validateManifest(manifest) {
264
+ const errors = [];
265
+ const warnings = [];
266
+ // Validate mode
267
+ const validModes = ['full', 'headless', 'api-only'];
268
+ if (manifest.mode && !validModes.includes(manifest.mode)) {
269
+ errors.push({
270
+ code: exports.ValidationCodes.INVALID_MODE,
271
+ path: 'mode',
272
+ message: `Invalid mode '${manifest.mode}'`,
273
+ suggestion: `Use one of: ${validModes.join(', ')}`,
274
+ });
275
+ }
276
+ // Validate database
277
+ errors.push(...validateDatabase(manifest));
278
+ // Validate auth
279
+ errors.push(...validateAuth(manifest));
280
+ // Collect entity names for relation validation
281
+ const entityNames = new Set(manifest.entities.map(e => e.name));
282
+ // Check for duplicate entity names
283
+ const seenNames = new Set();
284
+ for (const entity of manifest.entities) {
285
+ if (seenNames.has(entity.name)) {
286
+ errors.push({
287
+ code: exports.ValidationCodes.DUPLICATE_ENTITY,
288
+ path: entity.name,
289
+ message: `Duplicate entity name '${entity.name}'`,
290
+ suggestion: `Rename one of the entities`,
291
+ });
292
+ }
293
+ seenNames.add(entity.name);
294
+ }
295
+ // Validate each entity
296
+ const authEnabled = manifest.auth?.enabled || false;
297
+ for (const entity of manifest.entities) {
298
+ errors.push(...validateEntity(entity, entityNames, authEnabled));
299
+ }
300
+ // Validate global source
301
+ if (manifest.source && !manifest.source.baseUrl) {
302
+ errors.push({
303
+ code: exports.ValidationCodes.EXTERNAL_SOURCE_INVALID,
304
+ path: 'source.baseUrl',
305
+ message: `Global external source requires baseUrl`,
306
+ suggestion: `Add baseUrl to source, e.g., 'env:API_URL'`,
307
+ });
308
+ }
309
+ return {
310
+ valid: errors.length === 0,
311
+ errors,
312
+ warnings,
313
+ };
314
+ }
package/package.json ADDED
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "archetype-engine",
3
+ "version": "2.0.0",
4
+ "description": "Type-safe backend generator for Next.js. Define entities once, get Drizzle schemas, tRPC APIs, Zod validation, and React hooks instantly.",
5
+ "main": "dist/src/index.js",
6
+ "types": "dist/src/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/src/index.d.ts",
10
+ "import": "./dist/src/index.js",
11
+ "require": "./dist/src/index.js"
12
+ },
13
+ "./ai": {
14
+ "types": "./dist/src/ai/index.d.ts",
15
+ "import": "./dist/src/ai/index.js",
16
+ "require": "./dist/src/ai/index.js"
17
+ }
18
+ },
19
+ "bin": {
20
+ "archetype": "dist/src/cli.js"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md"
25
+ ],
26
+ "engines": {
27
+ "node": ">=20.0.0"
28
+ },
29
+ "scripts": {
30
+ "build": "tsc",
31
+ "prepublishOnly": "npm run build",
32
+ "test": "vitest",
33
+ "test:run": "vitest run",
34
+ "init": "node dist/src/cli.js init",
35
+ "generate": "node dist/src/cli.js generate"
36
+ },
37
+ "dependencies": {
38
+ "@clack/prompts": "^0.11.0",
39
+ "puppeteer": "^24.34.0",
40
+ "ts-node": "^10.9.2",
41
+ "zod": "^3.23.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.5.5",
45
+ "typedoc": "^0.28.15",
46
+ "typescript": "^5.9.3",
47
+ "vitest": "^4.0.16"
48
+ },
49
+ "peerDependencies": {
50
+ "typescript": ">=5.0.0"
51
+ },
52
+ "keywords": [
53
+ "nextjs",
54
+ "backend-generator",
55
+ "code-generation",
56
+ "drizzle",
57
+ "trpc",
58
+ "zod",
59
+ "react-query",
60
+ "type-safe",
61
+ "crud",
62
+ "api-generator",
63
+ "typescript",
64
+ "fullstack",
65
+ "scaffolding",
66
+ "boilerplate",
67
+ "v0",
68
+ "cursor",
69
+ "ai-backend",
70
+ "prisma-alternative",
71
+ "orm",
72
+ "schema-first",
73
+ "declarative",
74
+ "entity-framework"
75
+ ],
76
+ "author": "IFAKA",
77
+ "license": "MIT",
78
+ "repository": {
79
+ "type": "git",
80
+ "url": "git+https://github.com/IFAKA/archetype-engine.git"
81
+ },
82
+ "bugs": {
83
+ "url": "https://github.com/IFAKA/archetype-engine/issues"
84
+ },
85
+ "homepage": "https://archetype-engine.vercel.app"
86
+ }