@msbci/form-server 1.3.0 → 1.3.2

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 CHANGED
@@ -158,6 +158,33 @@ datasource db {
158
158
 
159
159
  All inputs validated with Zod. Errors returned as `{ status, message, data, errors }`.
160
160
 
161
+ ## v1.3.2
162
+
163
+ - **DataSourceConfig CRUD** — nouvelle table `data_source_configs` (`@@unique([code, scopeId])`, `onDelete: Cascade` depuis Scope). 6 nouveaux endpoints REST :
164
+ - `GET / POST /scopes/:scopeId/datasources`
165
+ - `GET / PUT / DELETE /datasources/:id`
166
+ - `GET /forms/:formId/datasources` — **endpoint agrégé** : renvoie `{ items: IDataSourceConfig[], scopeHeaders: IScopeHeaders[] }` (configs + headers décryptés des scopes du form, tous en un seul appel).
167
+ - **Chiffrement AES-256-GCM** des headers admin via `src/utils/encryption.ts`. Format `base64(iv):base64(authTag):base64(ciphertext)`, IV 12 bytes (recommandé GCM), auth tag 16 bytes.
168
+ - `MOSOBI_ENCRYPTION_KEY` (32 bytes en base64 ou 64 chars hex) est requis pour **écrire** des headers : `requireEncryption()` lève `503 Service Unavailable` sinon.
169
+ - **Lecture tolérante** : si la clé manque, `decrypt()` renvoie `{}` avec un warning console — la lecture n'est jamais bloquée (la form reste rendable).
170
+ - **Headers de Scope** : `Scope.headers String?` (chiffré JSON). Surfacé décrypté dans `IScope.headers` sur GET. Mergés avec `IDataSourceConfig.headersOverride` côté renderer (config gagne).
171
+ - Suppression d'un scope refusée en **409** si au moins une `DataSourceConfig` le référence (en plus des forms et templates existants).
172
+ - Nouveau helper `ApiError.serviceUnavailable(message)` pour les 503.
173
+ - Migration Postgres `20260524000000_datasource_config` fournie pour `apps/demo`.
174
+ - 9 nouveaux tests d'intégration (54 total) : CRUD complet, dédup code, agrégation par formId, refus 503 sans clé, chiffrement effectif en base (le bearer n'apparaît jamais en clair), suppression scope bloquée par data source.
175
+ - Tests serveur passent en `fileParallelism: false` pour éviter les courses sur la même `test.db`.
176
+
177
+ ## v1.3.1
178
+
179
+ - **Multi-scopes par formulaire** — la colonne `FormDefinition.scopeId` est remplacée par une table pivot `FormDefinitionScope` (`formId`, `scopeId`, `order`) avec `onDelete: Cascade` de chaque côté. L'ordre dans le pivot porte la **priorité** des scopes.
180
+ - `POST /forms` et `PUT /forms/:id` acceptent désormais `scopeIds: string[]` (validé par Zod). Le payload `scopeId` n'est plus reconnu.
181
+ - `GET /forms?scopeId=X` filtre via `scopes: { some: { scopeId } }` (transparent pour le client).
182
+ - `GET /forms/:id` et `GET /forms/:id/resolved` retournent `scopeIds` triés par `order` asc.
183
+ - `dbToFormDefinition` extrait `scopeIds` depuis la relation `scopes` ordonnée.
184
+ - Migration Postgres `20260523000000_scope_pivot` fournie pour `apps/demo` (drop column → create pivot + indexes + FKs). Côté serveur (SQLite test) : `prisma db push` synchronise le schéma au démarrage des tests.
185
+ - Suppression d'un scope refusée en **409** si au moins une ligne pivot le référence (utilise `formDefinitionScope.count`).
186
+ - 2 nouveaux tests d'intégration (45 total) : préservation de l'ordre des scopes sur `GET /forms/:id/resolved`, remplacement complet de la liste sur `PUT /forms/:id`.
187
+
161
188
  ## v1.3.0
162
189
 
163
190
  - **Scope** : CRUD complet (`/scopes`) + multi-tenant via `tenantId @default("default")`
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var formCore=require('@msbci/form-core'),zod=require('zod');var f=class d extends Error{constructor(n,i,p){super(i);this.statusCode=n;this.errors=p;this.name="ApiError";}static notFound(n="Resource not found"){return new d(404,n)}static badRequest(n,i){return new d(400,n,i)}static unauthorized(n="Unauthorized"){return new d(401,n)}static conflict(n){return new d(409,n)}};function v(d,e="Success"){return {status:200,message:e,data:d}}function E(d,e,n,i){return {status:200,message:"Success",data:{items:d,total:e,page:n,pageSize:i,totalPages:Math.ceil(e/i)}}}function m(d){return d==null?null:JSON.stringify(d)}function g(d){if(d)try{return JSON.parse(d)}catch{return}}function T(d){if(d!=null)return typeof d=="string"?d:JSON.stringify(d)}var x=class{constructor(e){this.prisma=e;}async getFormTypes(e){return this.prisma.formType.findMany({orderBy:{name:"asc"}})}async getFormType(e){let n=await this.prisma.formType.findUnique({where:{id:e}});if(!n)throw f.notFound("FormType not found");return n}async createFormType(e){return this.prisma.formType.create({data:{...e,metadata:m(e.metadata)}})}async updateFormType(e,n){let{metadata:i,...p}=n;return this.prisma.formType.update({where:{id:e},data:{...p,...i!==void 0?{metadata:m(i)}:{}}})}async deleteFormType(e){return this.prisma.formType.delete({where:{id:e}})}async getFormDefinitions(e){let n={};e.tenantId&&(n.tenantId=e.tenantId),e.search&&(n.OR=[{name:{contains:e.search}},{code:{contains:e.search}}]);let[i,p]=await Promise.all([this.prisma.formDefinition.findMany({where:n,include:{formType:true,_count:{select:{pages:true,submissions:true}}},skip:(e.page-1)*e.pageSize,take:e.pageSize,orderBy:{updatedAt:"desc"}}),this.prisma.formDefinition.count({where:n})]);return {items:i,total:p}}async getFormDefinition(e){let n=await this.prisma.formDefinition.findUnique({where:{id:e},include:{formType:true,pages:{orderBy:{order:"asc"},include:{variables:{where:{pageId:{not:null}},orderBy:{order:"asc"}},rosters:{orderBy:{order:"asc"},include:{variables:{orderBy:{order:"asc"}}}}}}}});if(!n)throw f.notFound("FormDefinition not found");return n}async createFormDefinition(e,n){return this.prisma.formDefinition.create({data:{...e,metadata:m(e.metadata),createdBy:n?.userId,updatedBy:n?.userId}})}async updateFormDefinition(e,n,i){let{metadata:p,...r}=n;return this.prisma.formDefinition.update({where:{id:e},data:{...r,...p!==void 0?{metadata:m(p)}:{},updatedBy:i?.userId}})}async getResolvedFormDefinition(e){let n=await this.getFormDefinition(e);return this.dbToFormDefinition(n)}async deleteFormDefinition(e){return this.prisma.formDefinition.delete({where:{id:e}})}async createFormPage(e,n){return this.prisma.formPage.create({data:{...n,formId:e,conditions:m(n.conditions),metadata:m(n.metadata)}})}async updateFormPage(e,n){let{conditions:i,metadata:p,...r}=n;return this.prisma.formPage.update({where:{id:e},data:{...r,...i!==void 0?{conditions:m(i)}:{},...p!==void 0?{metadata:m(p)}:{}}})}async deleteFormPage(e){return this.prisma.formPage.delete({where:{id:e}})}async createFormRoster(e,n){return this.prisma.formRoster.create({data:{...n,pageId:e,options:m(n.options),conditions:m(n.conditions),metadata:m(n.metadata)}})}async updateFormRoster(e,n){let{options:i,conditions:p,metadata:r,...c}=n;return this.prisma.formRoster.update({where:{id:e},data:{...c,...i!==void 0?{options:m(i)}:{},...p!==void 0?{conditions:m(p)}:{},...r!==void 0?{metadata:m(r)}:{}}})}async deleteFormRoster(e){return this.prisma.formRoster.delete({where:{id:e}})}async createFormVariable(e){if(!e.pageId&&!e.rosterId)throw f.badRequest("Variable must belong to a page or a roster");let{templateOverrides:n,...i}=e;return this.prisma.formVariable.create({data:{...i,defaultValue:e.defaultValue!==void 0?String(e.defaultValue):null,options:m(e.options),validationRules:m(e.validationRules),conditions:m(e.conditions),dataSourceDependencies:m(e.dataSourceDependencies),style:m(e.style),metadata:m(e.metadata),templateOverrides:m(n)}})}async updateFormVariable(e,n){let{options:i,validationRules:p,conditions:r,dataSourceDependencies:c,style:s,metadata:l,defaultValue:S,templateOverrides:a,...o}=n;return this.prisma.formVariable.update({where:{id:e},data:{...o,...S!==void 0?{defaultValue:String(S)}:{},...i!==void 0?{options:m(i)}:{},...p!==void 0?{validationRules:m(p)}:{},...r!==void 0?{conditions:m(r)}:{},...c!==void 0?{dataSourceDependencies:m(c)}:{},...s!==void 0?{style:m(s)}:{},...l!==void 0?{metadata:m(l)}:{},...a!==void 0?{templateOverrides:m(a)}:{}}})}async deleteFormVariable(e){return this.prisma.formVariable.delete({where:{id:e}})}async getSubmissions(e){let n={formId:e.formId};e.status&&(n.status=e.status),e.tenantId&&(n.tenantId=e.tenantId);let[i,p]=await Promise.all([this.prisma.formSubmission.findMany({where:n,skip:(e.page-1)*e.pageSize,take:e.pageSize,orderBy:{createdAt:"desc"}}),this.prisma.formSubmission.count({where:n})]);return {items:i,total:p}}async getSubmission(e){let n=await this.prisma.formSubmission.findUnique({where:{id:e}});if(!n)throw f.notFound("Submission not found");return n}async createSubmission(e,n){return this.prisma.formSubmission.create({data:{formId:e.formId,tenantId:e.tenantId,status:e.status??"draft",data:JSON.stringify(e.data),submittedBy:e.submittedBy,metadata:m(e.metadata),createdBy:n?.userId,updatedBy:n?.userId}})}async updateSubmission(e,n,i){return this.prisma.formSubmission.update({where:{id:e},data:{...n.status?{status:n.status}:{},...n.data?{data:JSON.stringify(n.data)}:{},...n.metadata!==void 0?{metadata:m(n.metadata)}:{},updatedBy:i?.userId}})}async exportForm(e){let n=await this.getFormDefinition(e),i=await this.dbToFormDefinition(n);return formCore.serializeForm(i)}async importForm(e,n){let i=formCore.deserializeForm(e),p=await this.createFormDefinition({code:i.code,name:T(i.name)??"",description:T(i.description),version:i.version,isPublished:i.isPublished,tenantId:n,formTypeId:i.formTypeId,scopeId:i.scopeId});for(let r of i.pages){let c=await this.createFormPage(p.id,{code:r.code,name:T(r.name)??"",order:r.order,isRepeatable:r.isRepeatable,repeatMinInstances:r.repeatConfig?.min,repeatMaxInstances:r.repeatConfig?.max,repeatControlVarCode:r.repeatConfig?.controlVariableCode,repeatInstanceLabel:T(r.repeatConfig?.instanceLabel)});for(let s of formCore.getPageVariables(r))await this.createFormVariable(this.extractVariableData(s,c.id,void 0));for(let s of formCore.getPageRosters(r)){let l=await this.createFormRoster(c.id,{code:s.code,name:T(s.name)??"",rosterType:s.rosterType,order:s.order,pilotVariableCode:s.pilotVariableCode,options:s.options});for(let S of s.variables)await this.createFormVariable(this.extractVariableData(S,void 0,l.id));}}return p.id}extractVariableData(e,n,i){return {code:e.code,name:e.name,type:e.type,order:e.order,pageId:n,rosterId:i,isRequired:e.isRequired,isReadonly:e.isReadonly,isHidden:e.isHidden,defaultValue:e.defaultValue,placeholder:e.placeholder,description:e.description,options:e.options,validationRules:e.validationRules,conditions:e.conditions,expression:e.expression,dataSourceId:e.dataSourceId,dataSourceDependencies:e.dataSourceDependencies,style:e.style,metadata:e.metadata,templateId:e.templateId,templateOverrides:e.templateOverrides}}async dbToFormDefinition(e,n=true){let i={id:e.id,code:e.code,name:e.name,description:e.description??void 0,version:e.version,isPublished:e.isPublished,formTypeId:e.formTypeId??void 0,scopeId:e.scopeId??void 0,metadata:g(e.metadata),pages:(e.pages??[]).map(s=>({id:s.id,code:s.code,name:s.name,order:s.order,isRepeatable:s.isRepeatable,repeatConfig:s.isRepeatable?{min:s.repeatMinInstances??void 0,max:s.repeatMaxInstances??void 0,controlVariableCode:s.repeatControlVarCode??void 0,instanceLabel:s.repeatInstanceLabel??void 0}:void 0,conditions:g(s.conditions)??[],variables:(s.variables??[]).map(l=>this.dbToVariable(l)),rosters:(s.rosters??[]).map(l=>({id:l.id,code:l.code,name:l.name,rosterType:l.rosterType,order:l.order,pilotVariableCode:l.pilotVariableCode??void 0,options:g(l.options),conditions:g(l.conditions)??[],variables:(l.variables??[]).map(S=>this.dbToVariable(S))}))}))};if(!n)return i;let p=formCore.collectTemplateIds(i);if(p.size===0)return i;let r=await this.prisma.variableTemplate.findMany({where:{id:{in:[...p]}}}),c=new Map(r.map(s=>[s.id,this.dbToTemplate(s)]));return formCore.resolveFormTemplates(i,c)}dbToVariable(e){return {id:e.id,code:e.code,name:e.name,type:e.type,order:e.order,isRequired:e.isRequired,isReadonly:e.isReadonly,isHidden:e.isHidden,defaultValue:e.defaultValue??void 0,placeholder:e.placeholder??void 0,description:e.description??void 0,options:g(e.options),validationRules:g(e.validationRules),conditions:g(e.conditions),expression:e.expression??void 0,dataSourceId:e.dataSourceId??void 0,dataSourceDependencies:g(e.dataSourceDependencies),style:g(e.style),metadata:g(e.metadata),templateId:e.templateId??void 0,templateOverrides:g(e.templateOverrides)}}dbToTemplate(e){return {id:e.id,code:e.code,name:B(e.name)??"",scopeId:e.scopeId,tenantId:e.tenantId??"default",variableType:e.variableType,description:B(e.description),placeholder:B(e.placeholder),isRequired:e.isRequired??void 0,isReadonly:e.isReadonly??void 0,isHidden:e.isHidden??void 0,options:g(e.options),validationRules:g(e.validationRules),conditions:g(e.conditions),expression:e.expression??void 0,dataSourceId:e.dataSourceId??void 0,dataSourceDependencies:g(e.dataSourceDependencies),style:g(e.style),metadata:g(e.metadata),createdAt:e.createdAt instanceof Date?e.createdAt.toISOString():e.createdAt,updatedAt:e.updatedAt instanceof Date?e.updatedAt.toISOString():e.updatedAt,createdBy:e.createdBy??void 0,updatedBy:e.updatedBy??void 0}}};function B(d){if(d!=null){if(d.startsWith("{"))try{return JSON.parse(d)}catch{return d}return d}}var L="default";function b(d){return d==null?null:JSON.stringify(d)}function I(d){if(d!=null)try{return JSON.parse(d)}catch{return}}function w(d){if(d!=null)return typeof d=="string"?d:JSON.stringify(d)}function F(d){if(d!=null){if(d.startsWith("{"))try{return JSON.parse(d)}catch{return d}return d}}function O(d,e){return e??d?.tenantId??L}var P=class{constructor(e){this.prisma=e;}async createScope(e,n){let i=O(n,e.tenantId);try{let p=await this.prisma.scope.create({data:{code:e.code,name:w(e.name)??"",description:w(e.description),tenantId:i,metadata:b(e.metadata),createdBy:n?.userId,updatedBy:n?.userId}});return this.dbToScope(p)}catch(p){throw W(p)?f.badRequest(`Scope code "${e.code}" already exists for tenant "${i}"`):p}}async updateScope(e,n,i){if(!await this.prisma.scope.findUnique({where:{id:e}}))throw f.notFound("Scope not found");let r=await this.prisma.scope.update({where:{id:e},data:{...n.name!==void 0?{name:w(n.name)??""}:{},...n.description!==void 0?{description:w(n.description)}:{},...n.metadata!==void 0?{metadata:b(n.metadata)}:{},updatedBy:i?.userId}});return this.dbToScope(r)}async deleteScope(e){if(!await this.prisma.scope.findUnique({where:{id:e}}))throw f.notFound("Scope not found");let[i,p]=await Promise.all([this.prisma.formDefinition.count({where:{scopeId:e}}),this.prisma.variableTemplate.count({where:{scopeId:e}})]);if(i>0||p>0)throw f.conflict(`Scope is in use (forms: ${i}, templates: ${p}). Remove dependents first.`);await this.prisma.scope.delete({where:{id:e}});}async listScopes(e,n){let i=O(n,e.tenantId),p=e.page??1,r=e.pageSize??50,[c,s]=await Promise.all([this.prisma.scope.findMany({where:{tenantId:i},skip:(p-1)*r,take:r,orderBy:{updatedAt:"desc"}}),this.prisma.scope.count({where:{tenantId:i}})]);return {items:c.map(l=>this.dbToScope(l)),total:s}}async getScopeById(e){let n=await this.prisma.scope.findUnique({where:{id:e}});if(!n)throw f.notFound("Scope not found");return this.dbToScope(n)}async createTemplate(e,n,i){let p=await this.prisma.scope.findUnique({where:{id:e}});if(!p)throw f.notFound("Scope not found");let r=O(i,n.tenantId)||p.tenantId;try{let c=await this.prisma.variableTemplate.create({data:{code:n.code,name:w(n.name)??"",scopeId:e,tenantId:r,variableType:n.variableType,description:w(n.description),placeholder:w(n.placeholder),isRequired:n.isRequired??!1,isReadonly:n.isReadonly??!1,isHidden:n.isHidden??!1,options:b(n.options),validationRules:b(n.validationRules),conditions:b(n.conditions),expression:n.expression,dataSourceId:n.dataSourceId,dataSourceDependencies:b(n.dataSourceDependencies),style:b(n.style),metadata:b(n.metadata),createdBy:i?.userId,updatedBy:i?.userId}});return this.dbToTemplate(c)}catch(c){throw W(c)?f.badRequest(`Template code "${n.code}" already exists in this scope`):c}}async updateTemplate(e,n,i){if("code"in n||"name"in n)throw f.badRequest("Template code and name are immutable");if(!await this.prisma.variableTemplate.findUnique({where:{id:e}}))throw f.notFound("Template not found");let r=await this.prisma.variableTemplate.update({where:{id:e},data:{...n.variableType!==void 0?{variableType:n.variableType}:{},...n.description!==void 0?{description:w(n.description)}:{},...n.placeholder!==void 0?{placeholder:w(n.placeholder)}:{},...n.isRequired!==void 0?{isRequired:n.isRequired}:{},...n.isReadonly!==void 0?{isReadonly:n.isReadonly}:{},...n.isHidden!==void 0?{isHidden:n.isHidden}:{},...n.options!==void 0?{options:b(n.options)}:{},...n.validationRules!==void 0?{validationRules:b(n.validationRules)}:{},...n.conditions!==void 0?{conditions:b(n.conditions)}:{},...n.expression!==void 0?{expression:n.expression}:{},...n.dataSourceId!==void 0?{dataSourceId:n.dataSourceId}:{},...n.dataSourceDependencies!==void 0?{dataSourceDependencies:b(n.dataSourceDependencies)}:{},...n.style!==void 0?{style:b(n.style)}:{},...n.metadata!==void 0?{metadata:b(n.metadata)}:{},updatedBy:i?.userId}});return this.dbToTemplate(r)}async deleteTemplate(e){if(!await this.prisma.variableTemplate.findUnique({where:{id:e}}))throw f.notFound("Template not found");await this.prisma.variableTemplate.delete({where:{id:e}});}async listTemplates(e,n){let i=n?.page??1,p=n?.pageSize??100,[r,c]=await Promise.all([this.prisma.variableTemplate.findMany({where:{scopeId:e},skip:(i-1)*p,take:p,orderBy:{updatedAt:"desc"}}),this.prisma.variableTemplate.count({where:{scopeId:e}})]);return {items:r.map(s=>this.dbToTemplate(s)),total:c}}async getTemplateById(e){let n=await this.prisma.variableTemplate.findUnique({where:{id:e}});if(!n)throw f.notFound("Template not found");return this.dbToTemplate(n)}async getTemplatesByIds(e){return e.length===0?[]:(await this.prisma.variableTemplate.findMany({where:{id:{in:e}}})).map(i=>this.dbToTemplate(i))}dbToScope(e){return {id:e.id,code:e.code,name:F(e.name)??"",description:F(e.description),tenantId:e.tenantId??L,metadata:I(e.metadata),createdAt:e.createdAt instanceof Date?e.createdAt.toISOString():e.createdAt,updatedAt:e.updatedAt instanceof Date?e.updatedAt.toISOString():e.updatedAt,createdBy:e.createdBy??void 0,updatedBy:e.updatedBy??void 0}}dbToTemplate(e){return {id:e.id,code:e.code,name:F(e.name)??"",scopeId:e.scopeId,tenantId:e.tenantId??L,variableType:e.variableType,description:F(e.description),placeholder:F(e.placeholder),isRequired:e.isRequired??void 0,isReadonly:e.isReadonly??void 0,isHidden:e.isHidden??void 0,options:I(e.options),validationRules:I(e.validationRules),conditions:I(e.conditions),expression:e.expression??void 0,dataSourceId:e.dataSourceId??void 0,dataSourceDependencies:I(e.dataSourceDependencies),style:I(e.style),metadata:I(e.metadata),createdAt:e.createdAt instanceof Date?e.createdAt.toISOString():e.createdAt,updatedAt:e.updatedAt instanceof Date?e.updatedAt.toISOString():e.updatedAt,createdBy:e.createdBy??void 0,updatedBy:e.updatedBy??void 0}}};function W(d){return typeof d=="object"&&d!==null&&"code"in d&&d.code==="P2002"}var M=async()=>({});var D=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),description:zod.z.string().max(1e3).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),j=D.partial(),V=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),description:zod.z.string().max(1e3).optional(),version:zod.z.string().default("1.0.0"),isPublished:zod.z.boolean().default(false),tenantId:zod.z.string().optional(),formTypeId:zod.z.string().optional(),scopeId:zod.z.string().optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),U=V.partial(),C=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),order:zod.z.number().int().min(0),isRepeatable:zod.z.boolean().default(false),repeatMinInstances:zod.z.number().int().min(0).optional(),repeatMaxInstances:zod.z.number().int().min(1).optional(),repeatControlVarCode:zod.z.string().optional(),repeatInstanceLabel:zod.z.string().optional(),conditions:zod.z.array(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),H=C.partial(),z=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),rosterType:zod.z.enum(["check","list","collection","collection_extend"]),order:zod.z.number().int().min(0),pilotVariableCode:zod.z.string().optional(),options:zod.z.array(zod.z.object({label:zod.z.string(),value:zod.z.unknown(),metadata:zod.z.record(zod.z.unknown()).optional()})).optional(),conditions:zod.z.array(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),J=z.partial(),k=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),type:zod.z.string().min(1),order:zod.z.number().int().min(0),isRequired:zod.z.boolean().default(false),isReadonly:zod.z.boolean().default(false),isHidden:zod.z.boolean().default(false),defaultValue:zod.z.unknown().optional(),placeholder:zod.z.string().optional(),description:zod.z.string().max(1e3).optional(),options:zod.z.array(zod.z.object({label:zod.z.string(),value:zod.z.unknown(),metadata:zod.z.record(zod.z.unknown()).optional()})).optional(),validationRules:zod.z.array(zod.z.object({type:zod.z.string(),value:zod.z.unknown().optional(),message:zod.z.string()})).optional(),conditions:zod.z.array(zod.z.unknown()).optional(),expression:zod.z.string().optional(),dataSourceId:zod.z.string().optional(),dataSourceDependencies:zod.z.record(zod.z.string()).optional(),style:zod.z.record(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional(),templateId:zod.z.string().optional(),templateOverrides:zod.z.record(zod.z.unknown()).optional()}),q=k.partial(),h=zod.z.union([zod.z.string(),zod.z.record(zod.z.string())]),Y=zod.z.object({code:zod.z.string().min(1).max(80),name:h,description:h.optional(),tenantId:zod.z.string().optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),Z=zod.z.object({name:h.optional(),description:h.optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),_=["text","textarea","number","date","datetime","time","select","multiselect","checkbox","radio","file","image","email","gps","rating","calculated","hidden","label","panel","richtext","listradio","photo"],K=zod.z.object({code:zod.z.string().min(1).max(80),name:h,variableType:zod.z.enum(_),tenantId:zod.z.string().optional(),description:h.optional(),placeholder:h.optional(),isRequired:zod.z.boolean().optional(),isReadonly:zod.z.boolean().optional(),isHidden:zod.z.boolean().optional(),options:zod.z.array(zod.z.object({label:h,value:zod.z.unknown(),metadata:zod.z.record(zod.z.unknown()).optional()})).optional(),validationRules:zod.z.array(zod.z.object({type:zod.z.string(),value:zod.z.unknown().optional(),message:h})).optional(),conditions:zod.z.array(zod.z.unknown()).optional(),expression:zod.z.string().optional(),dataSourceId:zod.z.string().optional(),dataSourceDependencies:zod.z.record(zod.z.string()).optional(),style:zod.z.record(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),Q=zod.z.object({variableType:zod.z.enum(_).optional(),description:h.optional(),placeholder:h.optional(),isRequired:zod.z.boolean().optional(),isReadonly:zod.z.boolean().optional(),isHidden:zod.z.boolean().optional(),options:zod.z.array(zod.z.object({label:h,value:zod.z.unknown(),metadata:zod.z.record(zod.z.unknown()).optional()})).optional(),validationRules:zod.z.array(zod.z.object({type:zod.z.string(),value:zod.z.unknown().optional(),message:h})).optional(),conditions:zod.z.array(zod.z.unknown()).optional(),expression:zod.z.string().optional(),dataSourceId:zod.z.string().optional(),dataSourceDependencies:zod.z.record(zod.z.string()).optional(),style:zod.z.record(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}).strict(),N=zod.z.object({formId:zod.z.string().min(1),tenantId:zod.z.string().optional(),status:zod.z.enum(["draft","submitted","approved","rejected","completed"]).default("draft"),data:zod.z.record(zod.z.unknown()),submittedBy:zod.z.string().optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),G=zod.z.object({status:zod.z.enum(["draft","submitted","approved","rejected","completed"]).optional(),data:zod.z.record(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),R=zod.z.object({page:zod.z.coerce.number().int().min(1).default(1),pageSize:zod.z.coerce.number().int().min(1).max(100).default(20),search:zod.z.string().optional(),tenantId:zod.z.string().optional()});var X=new WeakSet;async function se(d){await d.scope.upsert({where:{code_tenantId:{code:"default",tenantId:"default"}},update:{},create:{code:"default",name:JSON.stringify({fr:"Scope par d\xE9faut",en:"Default Scope"}),tenantId:"default"}});}function de(d){let{prisma:e,auth:n=M}=d;X.has(e)||(X.add(e),se(e).catch(a=>{console.error("[form-server] initializeDefaults failed:",a);}));let i=new x(e),p=new P(e),r=new Map;async function c(a){let o=await n({headers:a.headers,query:a.query});if(!o)throw f.unauthorized();return o}function s(a,o=200){return {status:o,body:v(a)}}function l(a,o,u,y){return {status:200,body:E(a,o,u,y)}}r.set("GET /form-types",async a=>{await c(a);let o=await i.getFormTypes();return s(o)}),r.set("GET /form-types/:id",async a=>(await c(a),s(await i.getFormType(a.params.id)))),r.set("POST /form-types",async a=>{await c(a);let o=D.parse(a.body);return s(await i.createFormType(o),201)}),r.set("PUT /form-types/:id",async a=>{await c(a);let o=j.parse(a.body);return s(await i.updateFormType(a.params.id,o))}),r.set("DELETE /form-types/:id",async a=>(await c(a),await i.deleteFormType(a.params.id),s(null,204))),r.set("GET /forms",async a=>{await c(a);let o=R.parse(a.query),{items:u,total:y}=await i.getFormDefinitions(o);return l(u,y,o.page,o.pageSize)}),r.set("GET /forms/:id",async a=>(await c(a),s(await i.getFormDefinition(a.params.id)))),r.set("GET /forms/:id/resolved",async a=>(await c(a),s(await i.getResolvedFormDefinition(a.params.id)))),r.set("POST /forms",async a=>{let o=await c(a),u=V.parse(a.body);return s(await i.createFormDefinition(u,o),201)}),r.set("PUT /forms/:id",async a=>{let o=await c(a),u=U.parse(a.body);return s(await i.updateFormDefinition(a.params.id,u,o))}),r.set("DELETE /forms/:id",async a=>(await c(a),await i.deleteFormDefinition(a.params.id),s(null,204))),r.set("GET /forms/:id/export",async a=>(await c(a),{status:200,body:await i.exportForm(a.params.id)})),r.set("POST /forms/import",async a=>{await c(a);let{json:o,tenantId:u}=a.body,y=await i.importForm(o,u);return s({formId:y},201)}),r.set("POST /forms/:formId/pages",async a=>{await c(a);let o=C.parse(a.body);return s(await i.createFormPage(a.params.formId,o),201)}),r.set("PUT /pages/:id",async a=>{await c(a);let o=H.parse(a.body);return s(await i.updateFormPage(a.params.id,o))}),r.set("DELETE /pages/:id",async a=>(await c(a),await i.deleteFormPage(a.params.id),s(null,204))),r.set("POST /pages/:pageId/rosters",async a=>{await c(a);let o=z.parse(a.body);return s(await i.createFormRoster(a.params.pageId,o),201)}),r.set("PUT /rosters/:id",async a=>{await c(a);let o=J.parse(a.body);return s(await i.updateFormRoster(a.params.id,o))}),r.set("DELETE /rosters/:id",async a=>(await c(a),await i.deleteFormRoster(a.params.id),s(null,204))),r.set("POST /pages/:pageId/variables",async a=>{await c(a);let o=k.parse(a.body);return s(await i.createFormVariable({...o,pageId:a.params.pageId}),201)}),r.set("POST /rosters/:rosterId/variables",async a=>{await c(a);let o=k.parse(a.body);return s(await i.createFormVariable({...o,rosterId:a.params.rosterId}),201)}),r.set("PUT /variables/:id",async a=>{await c(a);let o=q.parse(a.body);return s(await i.updateFormVariable(a.params.id,o))}),r.set("DELETE /variables/:id",async a=>(await c(a),await i.deleteFormVariable(a.params.id),s(null,204))),r.set("GET /forms/:formId/submissions",async a=>{await c(a);let o=R.parse(a.query),{items:u,total:y}=await i.getSubmissions({formId:a.params.formId,...o});return l(u,y,o.page,o.pageSize)}),r.set("GET /submissions/:id",async a=>(await c(a),s(await i.getSubmission(a.params.id)))),r.set("POST /submissions",async a=>{let o=await c(a),u=N.parse(a.body);return s(await i.createSubmission(u,o),201)}),r.set("PUT /submissions/:id",async a=>{let o=await c(a),u=G.parse(a.body);return s(await i.updateSubmission(a.params.id,u,o))}),r.set("GET /scopes",async a=>{let o=await c(a),u=R.parse(a.query),{items:y,total:A}=await p.listScopes({tenantId:u.tenantId,page:u.page,pageSize:u.pageSize},o);return l(y,A,u.page,u.pageSize)}),r.set("GET /scopes/:id",async a=>(await c(a),s(await p.getScopeById(a.params.id)))),r.set("POST /scopes",async a=>{let o=await c(a),u=Y.parse(a.body);return s(await p.createScope(u,o),201)}),r.set("PUT /scopes/:id",async a=>{let o=await c(a),u=Z.parse(a.body);return s(await p.updateScope(a.params.id,u,o))}),r.set("DELETE /scopes/:id",async a=>(await c(a),await p.deleteScope(a.params.id),s(null,204))),r.set("GET /scopes/:scopeId/templates",async a=>{await c(a);let o=R.parse(a.query),{items:u,total:y}=await p.listTemplates(a.params.scopeId,{page:o.page,pageSize:o.pageSize});return l(u,y,o.page,o.pageSize)}),r.set("POST /scopes/:scopeId/templates",async a=>{let o=await c(a),u=K.parse(a.body);return s(await p.createTemplate(a.params.scopeId,u,o),201)}),r.set("GET /templates/:id",async a=>(await c(a),s(await p.getTemplateById(a.params.id)))),r.set("PUT /templates/:id",async a=>{let o=await c(a),u=Q.parse(a.body);return s(await p.updateTemplate(a.params.id,u,o))}),r.set("DELETE /templates/:id",async a=>(await c(a),await p.deleteTemplate(a.params.id),s(null,204)));function S(a,o){for(let[u,y]of r){let[A,ee]=u.split(" ");if(A!==a)continue;let $=ce(ee,o);if($)return {handler:y,params:$}}return null}return {routes:r,handle:async a=>{try{let o=S(a.method,a.path);return o?(a.params=o.params,await o.handler(a)):{status:404,body:{status:404,message:"Route not found",data:null}}}catch(o){return o instanceof f?{status:o.statusCode,body:{status:o.statusCode,message:o.message,data:null,errors:o.errors}}:o instanceof Error&&o.name==="ZodError"?{status:400,body:{status:400,message:"Validation error",data:null,errors:o.issues?.map(y=>y.message)}}:{status:500,body:{status:500,message:"Internal server error",data:null}}}}}}function ce(d,e){let n=d.split("/").filter(Boolean),i=e.split("/").filter(Boolean);if(n.length!==i.length)return null;let p={};for(let r=0;r<n.length;r++){let c=n[r],s=i[r];if(c.startsWith(":"))p[c.slice(1)]=s;else if(c!==s)return null}return p}exports.ApiError=f;exports.FormService=x;exports.createFormDefinitionSchema=V;exports.createFormPageSchema=C;exports.createFormRosterSchema=z;exports.createFormRouter=de;exports.createFormTypeSchema=D;exports.createFormVariableSchema=k;exports.createSubmissionSchema=N;exports.noAuth=M;exports.paginatedResponse=E;exports.paginationSchema=R;exports.successResponse=v;exports.updateFormDefinitionSchema=U;exports.updateFormPageSchema=H;exports.updateFormRosterSchema=J;exports.updateFormTypeSchema=j;exports.updateFormVariableSchema=q;exports.updateSubmissionSchema=G;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';var formCore=require('@msbci/form-core'),crypto=require('crypto'),zod=require('zod');var l=class i extends Error{constructor(t,r,c){super(r);this.statusCode=t;this.errors=c;this.name="ApiError";}static notFound(t="Resource not found"){return new i(404,t)}static badRequest(t,r){return new i(400,t,r)}static unauthorized(t="Unauthorized"){return new i(401,t)}static conflict(t){return new i(409,t)}static serviceUnavailable(t){return new i(503,t)}};function q(i,e="Success"){return {status:200,message:e,data:i}}function j(i,e,t,r){return {status:200,message:"Success",data:{items:i,total:e,page:t,pageSize:r,totalPages:Math.ceil(e/r)}}}function f(i){return i==null?null:JSON.stringify(i)}function h(i){if(i)try{return JSON.parse(i)}catch{return}}function k(i){if(i!=null)return typeof i=="string"?i:JSON.stringify(i)}var C=class{constructor(e){this.prisma=e;}async getFormTypes(e){return this.prisma.formType.findMany({orderBy:{name:"asc"}})}async getFormType(e){let t=await this.prisma.formType.findUnique({where:{id:e}});if(!t)throw l.notFound("FormType not found");return t}async createFormType(e){return this.prisma.formType.create({data:{...e,metadata:f(e.metadata)}})}async updateFormType(e,t){let{metadata:r,...c}=t;return this.prisma.formType.update({where:{id:e},data:{...c,...r!==void 0?{metadata:f(r)}:{}}})}async deleteFormType(e){return this.prisma.formType.delete({where:{id:e}})}async getFormDefinitions(e){let t={};e.tenantId&&(t.tenantId=e.tenantId),e.scopeId&&(t.scopes={some:{scopeId:e.scopeId}}),e.search&&(t.OR=[{name:{contains:e.search}},{code:{contains:e.search}}]);let[r,c]=await Promise.all([this.prisma.formDefinition.findMany({where:t,include:{formType:true,_count:{select:{pages:true,submissions:true}}},skip:(e.page-1)*e.pageSize,take:e.pageSize,orderBy:{updatedAt:"desc"}}),this.prisma.formDefinition.count({where:t})]);return {items:r,total:c}}async getFormDefinition(e){let t=await this.prisma.formDefinition.findUnique({where:{id:e},include:{formType:true,scopes:{orderBy:{order:"asc"}},pages:{orderBy:{order:"asc"},include:{variables:{where:{pageId:{not:null}},orderBy:{order:"asc"}},rosters:{orderBy:{order:"asc"},include:{variables:{orderBy:{order:"asc"}}}}}}}});if(!t)throw l.notFound("FormDefinition not found");return t}async createFormDefinition(e,t){let{scopeIds:r,...c}=e;return this.prisma.formDefinition.create({data:{...c,metadata:f(c.metadata),createdBy:t?.userId,updatedBy:t?.userId,...r&&r.length>0?{scopes:{create:r.map((d,o)=>({scopeId:d,order:o}))}}:{}}})}async updateFormDefinition(e,t,r){let{metadata:c,scopeIds:d,...o}=t;return await this.prisma.formDefinition.update({where:{id:e},data:{...o,...c!==void 0?{metadata:f(c)}:{},updatedBy:r?.userId}}),d!==void 0&&(await this.prisma.formDefinitionScope.deleteMany({where:{formId:e}}),d.length>0&&await this.prisma.formDefinitionScope.createMany({data:d.map((u,p)=>({formId:e,scopeId:u,order:p}))})),this.prisma.formDefinition.findUnique({where:{id:e},include:{scopes:{orderBy:{order:"asc"}}}})}async getResolvedFormDefinition(e){let t=await this.getFormDefinition(e);return this.dbToFormDefinition(t)}async deleteFormDefinition(e){return this.prisma.formDefinition.delete({where:{id:e}})}async createFormPage(e,t){return this.prisma.formPage.create({data:{...t,formId:e,conditions:f(t.conditions),metadata:f(t.metadata)}})}async updateFormPage(e,t){let{conditions:r,metadata:c,...d}=t;return this.prisma.formPage.update({where:{id:e},data:{...d,...r!==void 0?{conditions:f(r)}:{},...c!==void 0?{metadata:f(c)}:{}}})}async deleteFormPage(e){return this.prisma.formPage.delete({where:{id:e}})}async createFormRoster(e,t){return this.prisma.formRoster.create({data:{...t,pageId:e,options:f(t.options),conditions:f(t.conditions),metadata:f(t.metadata)}})}async updateFormRoster(e,t){let{options:r,conditions:c,metadata:d,...o}=t;return this.prisma.formRoster.update({where:{id:e},data:{...o,...r!==void 0?{options:f(r)}:{},...c!==void 0?{conditions:f(c)}:{},...d!==void 0?{metadata:f(d)}:{}}})}async deleteFormRoster(e){return this.prisma.formRoster.delete({where:{id:e}})}async createFormVariable(e){if(!e.pageId&&!e.rosterId)throw l.badRequest("Variable must belong to a page or a roster");let{templateOverrides:t,...r}=e;return this.prisma.formVariable.create({data:{...r,defaultValue:e.defaultValue!==void 0?String(e.defaultValue):null,options:f(e.options),validationRules:f(e.validationRules),conditions:f(e.conditions),dataSourceDependencies:f(e.dataSourceDependencies),style:f(e.style),metadata:f(e.metadata),templateOverrides:f(t)}})}async updateFormVariable(e,t){let{options:r,validationRules:c,conditions:d,dataSourceDependencies:o,style:u,metadata:p,defaultValue:g,templateOverrides:R,...a}=t;return this.prisma.formVariable.update({where:{id:e},data:{...a,...g!==void 0?{defaultValue:String(g)}:{},...r!==void 0?{options:f(r)}:{},...c!==void 0?{validationRules:f(c)}:{},...d!==void 0?{conditions:f(d)}:{},...o!==void 0?{dataSourceDependencies:f(o)}:{},...u!==void 0?{style:f(u)}:{},...p!==void 0?{metadata:f(p)}:{},...R!==void 0?{templateOverrides:f(R)}:{}}})}async deleteFormVariable(e){return this.prisma.formVariable.delete({where:{id:e}})}async getSubmissions(e){let t={formId:e.formId};e.status&&(t.status=e.status),e.tenantId&&(t.tenantId=e.tenantId);let[r,c]=await Promise.all([this.prisma.formSubmission.findMany({where:t,skip:(e.page-1)*e.pageSize,take:e.pageSize,orderBy:{createdAt:"desc"}}),this.prisma.formSubmission.count({where:t})]);return {items:r,total:c}}async getSubmission(e){let t=await this.prisma.formSubmission.findUnique({where:{id:e}});if(!t)throw l.notFound("Submission not found");return t}async createSubmission(e,t){return this.prisma.formSubmission.create({data:{formId:e.formId,tenantId:e.tenantId,status:e.status??"draft",data:JSON.stringify(e.data),submittedBy:e.submittedBy,metadata:f(e.metadata),createdBy:t?.userId,updatedBy:t?.userId}})}async updateSubmission(e,t,r){return this.prisma.formSubmission.update({where:{id:e},data:{...t.status?{status:t.status}:{},...t.data?{data:JSON.stringify(t.data)}:{},...t.metadata!==void 0?{metadata:f(t.metadata)}:{},updatedBy:r?.userId}})}async exportForm(e){let t=await this.getFormDefinition(e),r=await this.dbToFormDefinition(t);return formCore.serializeForm(r)}async importForm(e,t){let r=formCore.deserializeForm(e),c=await this.createFormDefinition({code:r.code,name:k(r.name)??"",description:k(r.description),version:r.version,isPublished:r.isPublished,tenantId:t,formTypeId:r.formTypeId,scopeIds:r.scopeIds});for(let d of r.pages){let o=await this.createFormPage(c.id,{code:d.code,name:k(d.name)??"",order:d.order,isRepeatable:d.isRepeatable,repeatMinInstances:d.repeatConfig?.min,repeatMaxInstances:d.repeatConfig?.max,repeatControlVarCode:d.repeatConfig?.controlVariableCode,repeatInstanceLabel:k(d.repeatConfig?.instanceLabel)});for(let u of formCore.getPageVariables(d))await this.createFormVariable(this.extractVariableData(u,o.id,void 0));for(let u of formCore.getPageRosters(d)){let p=await this.createFormRoster(o.id,{code:u.code,name:k(u.name)??"",rosterType:u.rosterType,order:u.order,pilotVariableCode:u.pilotVariableCode,options:u.options});for(let g of u.variables)await this.createFormVariable(this.extractVariableData(g,void 0,p.id));}}return c.id}extractVariableData(e,t,r){return {code:e.code,name:e.name,type:e.type,order:e.order,pageId:t,rosterId:r,isRequired:e.isRequired,isReadonly:e.isReadonly,isHidden:e.isHidden,defaultValue:e.defaultValue,placeholder:e.placeholder,description:e.description,options:e.options,validationRules:e.validationRules,conditions:e.conditions,expression:e.expression,dataSourceId:e.dataSourceId,dataSourceDependencies:e.dataSourceDependencies,style:e.style,metadata:e.metadata,templateId:e.templateId,templateOverrides:e.templateOverrides}}async dbToFormDefinition(e,t=true){let r=Array.isArray(e.scopes)?e.scopes.slice().sort((p,g)=>p.order-g.order).map(p=>p.scopeId):void 0,c={id:e.id,code:e.code,name:e.name,description:e.description??void 0,version:e.version,isPublished:e.isPublished,formTypeId:e.formTypeId??void 0,scopeIds:r&&r.length>0?r:void 0,metadata:h(e.metadata),pages:(e.pages??[]).map(p=>({id:p.id,code:p.code,name:p.name,order:p.order,isRepeatable:p.isRepeatable,repeatConfig:p.isRepeatable?{min:p.repeatMinInstances??void 0,max:p.repeatMaxInstances??void 0,controlVariableCode:p.repeatControlVarCode??void 0,instanceLabel:p.repeatInstanceLabel??void 0}:void 0,conditions:h(p.conditions)??[],variables:(p.variables??[]).map(g=>this.dbToVariable(g)),rosters:(p.rosters??[]).map(g=>({id:g.id,code:g.code,name:g.name,rosterType:g.rosterType,order:g.order,pilotVariableCode:g.pilotVariableCode??void 0,options:h(g.options),conditions:h(g.conditions)??[],variables:(g.variables??[]).map(R=>this.dbToVariable(R))}))}))};if(!t)return c;let d=formCore.collectTemplateIds(c);if(d.size===0)return c;let o=await this.prisma.variableTemplate.findMany({where:{id:{in:[...d]}}}),u=new Map(o.map(p=>[p.id,this.dbToTemplate(p)]));return formCore.resolveFormTemplates(c,u)}dbToVariable(e){return {id:e.id,code:e.code,name:e.name,type:e.type,order:e.order,isRequired:e.isRequired,isReadonly:e.isReadonly,isHidden:e.isHidden,defaultValue:e.defaultValue??void 0,placeholder:e.placeholder??void 0,description:e.description??void 0,options:h(e.options),validationRules:h(e.validationRules),conditions:h(e.conditions),expression:e.expression??void 0,dataSourceId:e.dataSourceId??void 0,dataSourceDependencies:h(e.dataSourceDependencies),style:h(e.style),metadata:h(e.metadata),templateId:e.templateId??void 0,templateOverrides:h(e.templateOverrides)}}dbToTemplate(e){return {id:e.id,code:e.code,name:J(e.name)??"",scopeId:e.scopeId,tenantId:e.tenantId??"default",variableType:e.variableType,description:J(e.description),placeholder:J(e.placeholder),isRequired:e.isRequired??void 0,isReadonly:e.isReadonly??void 0,isHidden:e.isHidden??void 0,options:h(e.options),validationRules:h(e.validationRules),conditions:h(e.conditions),expression:e.expression??void 0,dataSourceId:e.dataSourceId??void 0,dataSourceDependencies:h(e.dataSourceDependencies),style:h(e.style),metadata:h(e.metadata),createdAt:e.createdAt instanceof Date?e.createdAt.toISOString():e.createdAt,updatedAt:e.updatedAt instanceof Date?e.updatedAt.toISOString():e.updatedAt,createdBy:e.createdBy??void 0,updatedBy:e.updatedBy??void 0}}};function J(i){if(i!=null){if(i.startsWith("{"))try{return JSON.parse(i)}catch{return i}return i}}var ae="aes-256-gcm",B="MOSOBI_ENCRYPTION_KEY",re=12,xe=16;function G(){let i=process.env[B];if(!i)throw l.serviceUnavailable(`${B} is not configured \u2014 header encryption is unavailable`);let e=i.trim(),t;if(/^[A-Za-z0-9+/=]+$/.test(e)&&(t=Buffer.from(e,"base64"),t.length===32))return t;if(/^[0-9a-fA-F]+$/.test(e)&&e.length===64)return Buffer.from(e,"hex");throw l.serviceUnavailable(`${B} must be 32 bytes (base64 or 64-char hex)`)}function x(i){let e=G(),t=crypto.randomBytes(re),r=crypto.createCipheriv(ae,e,t),c=Buffer.from(JSON.stringify(i),"utf8"),d=Buffer.concat([r.update(c),r.final()]),o=r.getAuthTag();return [t.toString("base64"),o.toString("base64"),d.toString("base64")].join(":")}function F(i){let e;try{e=G();}catch{return console.warn(`[form-server] ${B} is missing \u2014 encrypted headers returned as {}`),{}}let t=i.split(":");if(t.length!==3)return console.warn("[form-server] encrypted header payload is malformed \u2014 returning {}"),{};try{let r=Buffer.from(t[0],"base64"),c=Buffer.from(t[1],"base64"),d=Buffer.from(t[2],"base64");if(r.length!==re||c.length!==xe)return console.warn("[form-server] encrypted header IV/tag length mismatch \u2014 returning {}"),{};let o=crypto.createDecipheriv(ae,e,r);o.setAuthTag(c);let u=Buffer.concat([o.update(d),o.final()]).toString("utf8"),p=JSON.parse(u);return p&&typeof p=="object"?p:{}}catch(r){return console.warn("[form-server] failed to decrypt headers \u2014 returning {}",r),{}}}function D(){G();}var $="default";function b(i){return i==null?null:JSON.stringify(i)}function I(i){if(i!=null)try{return JSON.parse(i)}catch{return}}function w(i){if(i!=null)return typeof i=="string"?i:JSON.stringify(i)}function V(i){if(i!=null){if(i.startsWith("{"))try{return JSON.parse(i)}catch{return i}return i}}function N(i,e){return e??i?.tenantId??$}var A=class{constructor(e){this.prisma=e;}async createScope(e,t){let r=N(t,e.tenantId),c=null;e.headers!==void 0&&(D(),c=x(e.headers));try{let d=await this.prisma.scope.create({data:{code:e.code,name:w(e.name)??"",description:w(e.description),tenantId:r,metadata:b(e.metadata),headers:c,createdBy:t?.userId,updatedBy:t?.userId}});return this.dbToScope(d)}catch(d){throw ie(d)?l.badRequest(`Scope code "${e.code}" already exists for tenant "${r}"`):d}}async updateScope(e,t,r){if(!await this.prisma.scope.findUnique({where:{id:e}}))throw l.notFound("Scope not found");let d;t.headers!==void 0&&(D(),d=x(t.headers));let o=await this.prisma.scope.update({where:{id:e},data:{...t.name!==void 0?{name:w(t.name)??""}:{},...t.description!==void 0?{description:w(t.description)}:{},...t.metadata!==void 0?{metadata:b(t.metadata)}:{},...d!==void 0?{headers:d}:{},updatedBy:r?.userId}});return this.dbToScope(o)}async getScopeHeaders(e){let t=await this.prisma.scope.findUnique({where:{id:e},select:{headers:true}});return !t||!t.headers?{}:F(t.headers)}async deleteScope(e){if(!await this.prisma.scope.findUnique({where:{id:e}}))throw l.notFound("Scope not found");let[r,c,d]=await Promise.all([this.prisma.formDefinitionScope.count({where:{scopeId:e}}),this.prisma.variableTemplate.count({where:{scopeId:e}}),this.prisma.dataSourceConfig.count({where:{scopeId:e}})]);if(r>0||c>0||d>0)throw l.conflict(`Scope is in use (forms: ${r}, templates: ${c}, dataSources: ${d}). Remove dependents first.`);await this.prisma.scope.delete({where:{id:e}});}async listScopes(e,t){let r=N(t,e.tenantId),c=e.page??1,d=e.pageSize??50,[o,u]=await Promise.all([this.prisma.scope.findMany({where:{tenantId:r},skip:(c-1)*d,take:d,orderBy:{updatedAt:"desc"}}),this.prisma.scope.count({where:{tenantId:r}})]);return {items:o.map(p=>this.dbToScope(p)),total:u}}async getScopeById(e){let t=await this.prisma.scope.findUnique({where:{id:e}});if(!t)throw l.notFound("Scope not found");return this.dbToScope(t)}async createTemplate(e,t,r){let c=await this.prisma.scope.findUnique({where:{id:e}});if(!c)throw l.notFound("Scope not found");let d=N(r,t.tenantId)||c.tenantId;try{let o=await this.prisma.variableTemplate.create({data:{code:t.code,name:w(t.name)??"",scopeId:e,tenantId:d,variableType:t.variableType,description:w(t.description),placeholder:w(t.placeholder),isRequired:t.isRequired??!1,isReadonly:t.isReadonly??!1,isHidden:t.isHidden??!1,options:b(t.options),validationRules:b(t.validationRules),conditions:b(t.conditions),expression:t.expression,dataSourceId:t.dataSourceId,dataSourceDependencies:b(t.dataSourceDependencies),style:b(t.style),metadata:b(t.metadata),createdBy:r?.userId,updatedBy:r?.userId}});return this.dbToTemplate(o)}catch(o){throw ie(o)?l.badRequest(`Template code "${t.code}" already exists in this scope`):o}}async updateTemplate(e,t,r){if("code"in t||"name"in t)throw l.badRequest("Template code and name are immutable");if(!await this.prisma.variableTemplate.findUnique({where:{id:e}}))throw l.notFound("Template not found");let d=await this.prisma.variableTemplate.update({where:{id:e},data:{...t.variableType!==void 0?{variableType:t.variableType}:{},...t.description!==void 0?{description:w(t.description)}:{},...t.placeholder!==void 0?{placeholder:w(t.placeholder)}:{},...t.isRequired!==void 0?{isRequired:t.isRequired}:{},...t.isReadonly!==void 0?{isReadonly:t.isReadonly}:{},...t.isHidden!==void 0?{isHidden:t.isHidden}:{},...t.options!==void 0?{options:b(t.options)}:{},...t.validationRules!==void 0?{validationRules:b(t.validationRules)}:{},...t.conditions!==void 0?{conditions:b(t.conditions)}:{},...t.expression!==void 0?{expression:t.expression}:{},...t.dataSourceId!==void 0?{dataSourceId:t.dataSourceId}:{},...t.dataSourceDependencies!==void 0?{dataSourceDependencies:b(t.dataSourceDependencies)}:{},...t.style!==void 0?{style:b(t.style)}:{},...t.metadata!==void 0?{metadata:b(t.metadata)}:{},updatedBy:r?.userId}});return this.dbToTemplate(d)}async deleteTemplate(e){if(!await this.prisma.variableTemplate.findUnique({where:{id:e}}))throw l.notFound("Template not found");await this.prisma.variableTemplate.delete({where:{id:e}});}async listTemplates(e,t){let r=t?.page??1,c=t?.pageSize??100,[d,o]=await Promise.all([this.prisma.variableTemplate.findMany({where:{scopeId:e},skip:(r-1)*c,take:c,orderBy:{updatedAt:"desc"}}),this.prisma.variableTemplate.count({where:{scopeId:e}})]);return {items:d.map(u=>this.dbToTemplate(u)),total:o}}async getTemplateById(e){let t=await this.prisma.variableTemplate.findUnique({where:{id:e}});if(!t)throw l.notFound("Template not found");return this.dbToTemplate(t)}async getTemplatesByIds(e){return e.length===0?[]:(await this.prisma.variableTemplate.findMany({where:{id:{in:e}}})).map(r=>this.dbToTemplate(r))}dbToScope(e){let t=e.headers?F(e.headers):void 0;return {id:e.id,code:e.code,name:V(e.name)??"",description:V(e.description),tenantId:e.tenantId??$,metadata:I(e.metadata),headers:t,createdAt:e.createdAt instanceof Date?e.createdAt.toISOString():e.createdAt,updatedAt:e.updatedAt instanceof Date?e.updatedAt.toISOString():e.updatedAt,createdBy:e.createdBy??void 0,updatedBy:e.updatedBy??void 0}}dbToTemplate(e){return {id:e.id,code:e.code,name:V(e.name)??"",scopeId:e.scopeId,tenantId:e.tenantId??$,variableType:e.variableType,description:V(e.description),placeholder:V(e.placeholder),isRequired:e.isRequired??void 0,isReadonly:e.isReadonly??void 0,isHidden:e.isHidden??void 0,options:I(e.options),validationRules:I(e.validationRules),conditions:I(e.conditions),expression:e.expression??void 0,dataSourceId:e.dataSourceId??void 0,dataSourceDependencies:I(e.dataSourceDependencies),style:I(e.style),metadata:I(e.metadata),createdAt:e.createdAt instanceof Date?e.createdAt.toISOString():e.createdAt,updatedAt:e.updatedAt instanceof Date?e.updatedAt.toISOString():e.updatedAt,createdBy:e.createdBy??void 0,updatedBy:e.updatedBy??void 0}}};function ie(i){return typeof i=="object"&&i!==null&&"code"in i&&i.code==="P2002"}function E(i){return i==null?null:JSON.stringify(i)}function oe(i){if(i!=null)try{return JSON.parse(i)}catch{return}}function se(i){return i==null?"":typeof i=="string"?i:JSON.stringify(i)}function Fe(i){if(i==null)return "";if(i.startsWith("{"))try{return JSON.parse(i)}catch{return i}return i}var O=class{constructor(e){this.prisma=e;}async createDataSource(e,t,r){if(!await this.prisma.scope.findUnique({where:{id:e}}))throw l.notFound("Scope not found");let d=null;t.headersOverride!==void 0&&(D(),d=x(t.headersOverride));try{let o=await this.prisma.dataSourceConfig.create({data:{code:t.code,name:se(t.name),scopeId:e,url:t.url,method:t.method??"GET",queryParam:t.queryParam??"q",valueField:t.valueField,labelField:t.labelField,headersOverride:d,dependencies:E(t.dependencies),metadata:E(t.metadata),createdBy:r?.userId,updatedBy:r?.userId}});return this.dbToConfig(o)}catch(o){throw De(o)?l.badRequest(`DataSource code "${t.code}" already exists in this scope`):o}}async updateDataSource(e,t,r){if(!await this.prisma.dataSourceConfig.findUnique({where:{id:e}}))throw l.notFound("DataSource not found");let d;t.headersOverride!==void 0&&(D(),d=x(t.headersOverride));let o=await this.prisma.dataSourceConfig.update({where:{id:e},data:{...t.code!==void 0?{code:t.code}:{},...t.name!==void 0?{name:se(t.name)}:{},...t.url!==void 0?{url:t.url}:{},...t.method!==void 0?{method:t.method}:{},...t.queryParam!==void 0?{queryParam:t.queryParam}:{},...t.valueField!==void 0?{valueField:t.valueField}:{},...t.labelField!==void 0?{labelField:t.labelField}:{},...d!==void 0?{headersOverride:d}:{},...t.dependencies!==void 0?{dependencies:E(t.dependencies)}:{},...t.metadata!==void 0?{metadata:E(t.metadata)}:{},updatedBy:r?.userId}});return this.dbToConfig(o)}async deleteDataSource(e){if(!await this.prisma.dataSourceConfig.findUnique({where:{id:e}}))throw l.notFound("DataSource not found");await this.prisma.dataSourceConfig.delete({where:{id:e}});}async listDataSources(e,t){let r=t?.page??1,c=t?.pageSize??100,[d,o]=await Promise.all([this.prisma.dataSourceConfig.findMany({where:{scopeId:e},skip:(r-1)*c,take:c,orderBy:{updatedAt:"desc"}}),this.prisma.dataSourceConfig.count({where:{scopeId:e}})]);return {items:d.map(u=>this.dbToConfig(u)),total:o}}async getDataSourceById(e){let t=await this.prisma.dataSourceConfig.findUnique({where:{id:e}});if(!t)throw l.notFound("DataSource not found");return this.dbToConfig(t)}async getDataSourcesByScopeIds(e){if(e.length===0)return {items:[],scopeHeaders:[]};let[t,r]=await Promise.all([this.prisma.dataSourceConfig.findMany({where:{scopeId:{in:e}},orderBy:{updatedAt:"desc"}}),this.prisma.scope.findMany({where:{id:{in:e}},select:{id:true,headers:true}})]),c=r.map(d=>({scopeId:d.id,headers:d.headers?F(d.headers):{}}));return {items:t.map(d=>this.dbToConfig(d)),scopeHeaders:c}}dbToConfig(e){return {id:e.id,code:e.code,name:Fe(e.name),scopeId:e.scopeId,url:e.url,method:e.method??"GET",queryParam:e.queryParam??void 0,valueField:e.valueField,labelField:e.labelField,headersOverride:e.headersOverride?F(e.headersOverride):void 0,dependencies:oe(e.dependencies),metadata:oe(e.metadata),createdAt:e.createdAt instanceof Date?e.createdAt.toISOString():e.createdAt,updatedAt:e.updatedAt instanceof Date?e.updatedAt.toISOString():e.updatedAt,createdBy:e.createdBy??void 0,updatedBy:e.updatedBy??void 0}}};function De(i){return typeof i=="object"&&i!==null&&"code"in i&&i.code==="P2002"}var Y=async()=>({});var z=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),description:zod.z.string().max(1e3).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),_=z.partial(),L=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),description:zod.z.string().max(1e3).optional(),version:zod.z.string().default("1.0.0"),isPublished:zod.z.boolean().default(false),tenantId:zod.z.string().optional(),formTypeId:zod.z.string().optional(),scopeIds:zod.z.array(zod.z.string()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),W=L.partial(),U=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),order:zod.z.number().int().min(0),isRepeatable:zod.z.boolean().default(false),repeatMinInstances:zod.z.number().int().min(0).optional(),repeatMaxInstances:zod.z.number().int().min(1).optional(),repeatControlVarCode:zod.z.string().optional(),repeatInstanceLabel:zod.z.string().optional(),conditions:zod.z.array(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),K=U.partial(),H=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),rosterType:zod.z.enum(["check","list","collection","collection_extend"]),order:zod.z.number().int().min(0),pilotVariableCode:zod.z.string().optional(),options:zod.z.array(zod.z.object({label:zod.z.string(),value:zod.z.unknown(),metadata:zod.z.record(zod.z.unknown()).optional()})).optional(),conditions:zod.z.array(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),Z=H.partial(),v=zod.z.object({code:zod.z.string().min(1).max(50),name:zod.z.string().min(1).max(200),type:zod.z.string().min(1),order:zod.z.number().int().min(0),isRequired:zod.z.boolean().default(false),isReadonly:zod.z.boolean().default(false),isHidden:zod.z.boolean().default(false),defaultValue:zod.z.unknown().optional(),placeholder:zod.z.string().optional(),description:zod.z.string().max(1e3).optional(),options:zod.z.array(zod.z.object({label:zod.z.string(),value:zod.z.unknown(),metadata:zod.z.record(zod.z.unknown()).optional()})).optional(),validationRules:zod.z.array(zod.z.object({type:zod.z.string(),value:zod.z.unknown().optional(),message:zod.z.string()})).optional(),conditions:zod.z.array(zod.z.unknown()).optional(),expression:zod.z.string().optional(),dataSourceId:zod.z.string().optional(),dataSourceDependencies:zod.z.record(zod.z.string()).optional(),style:zod.z.record(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional(),templateId:zod.z.string().optional(),templateOverrides:zod.z.record(zod.z.unknown()).optional()}),Q=v.partial(),S=zod.z.union([zod.z.string(),zod.z.record(zod.z.string())]),de=zod.z.object({code:zod.z.string().min(1).max(80),name:S,description:S.optional(),tenantId:zod.z.string().optional(),metadata:zod.z.record(zod.z.unknown()).optional(),headers:zod.z.record(zod.z.string()).optional()}),ce=zod.z.object({name:S.optional(),description:S.optional(),metadata:zod.z.record(zod.z.unknown()).optional(),headers:zod.z.record(zod.z.string()).optional()}),ue=["text","textarea","number","date","datetime","time","select","multiselect","checkbox","radio","file","image","email","gps","rating","calculated","hidden","label","panel","richtext","listradio","photo"],pe=zod.z.object({code:zod.z.string().min(1).max(80),name:S,variableType:zod.z.enum(ue),tenantId:zod.z.string().optional(),description:S.optional(),placeholder:S.optional(),isRequired:zod.z.boolean().optional(),isReadonly:zod.z.boolean().optional(),isHidden:zod.z.boolean().optional(),options:zod.z.array(zod.z.object({label:S,value:zod.z.unknown(),metadata:zod.z.record(zod.z.unknown()).optional()})).optional(),validationRules:zod.z.array(zod.z.object({type:zod.z.string(),value:zod.z.unknown().optional(),message:S})).optional(),conditions:zod.z.array(zod.z.unknown()).optional(),expression:zod.z.string().optional(),dataSourceId:zod.z.string().optional(),dataSourceDependencies:zod.z.record(zod.z.string()).optional(),style:zod.z.record(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),me=zod.z.object({variableType:zod.z.enum(ue).optional(),description:S.optional(),placeholder:S.optional(),isRequired:zod.z.boolean().optional(),isReadonly:zod.z.boolean().optional(),isHidden:zod.z.boolean().optional(),options:zod.z.array(zod.z.object({label:S,value:zod.z.unknown(),metadata:zod.z.record(zod.z.unknown()).optional()})).optional(),validationRules:zod.z.array(zod.z.object({type:zod.z.string(),value:zod.z.unknown().optional(),message:S})).optional(),conditions:zod.z.array(zod.z.unknown()).optional(),expression:zod.z.string().optional(),dataSourceId:zod.z.string().optional(),dataSourceDependencies:zod.z.record(zod.z.string()).optional(),style:zod.z.record(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}).strict(),X=zod.z.object({code:zod.z.string().min(1).max(80),name:S,url:zod.z.string().url(),method:zod.z.enum(["GET","POST"]).default("GET"),queryParam:zod.z.string().default("q"),valueField:zod.z.string().min(1),labelField:zod.z.string().min(1),headersOverride:zod.z.record(zod.z.string()).optional(),dependencies:zod.z.record(zod.z.string()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),le=X.partial(),ee=zod.z.object({formId:zod.z.string().min(1),tenantId:zod.z.string().optional(),status:zod.z.enum(["draft","submitted","approved","rejected","completed"]).default("draft"),data:zod.z.record(zod.z.unknown()),submittedBy:zod.z.string().optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),te=zod.z.object({status:zod.z.enum(["draft","submitted","approved","rejected","completed"]).optional(),data:zod.z.record(zod.z.unknown()).optional(),metadata:zod.z.record(zod.z.unknown()).optional()}),T=zod.z.object({page:zod.z.coerce.number().int().min(1).default(1),pageSize:zod.z.coerce.number().int().min(1).max(100).default(20),search:zod.z.string().optional(),tenantId:zod.z.string().optional()});var fe=new WeakSet;async function Pe(i){await i.scope.upsert({where:{code_tenantId:{code:"default",tenantId:"default"}},update:{},create:{code:"default",name:JSON.stringify({fr:"Scope par d\xE9faut",en:"Default Scope"}),tenantId:"default"}});}function ke(i){let{prisma:e,auth:t=Y}=i;fe.has(e)||(fe.add(e),Pe(e).catch(a=>{console.error("[form-server] initializeDefaults failed:",a);}));let r=new C(e),c=new A(e),d=new O(e),o=new Map;async function u(a){let s=await t({headers:a.headers,query:a.query});if(!s)throw l.unauthorized();return s}function p(a,s=200){return {status:s,body:q(a)}}function g(a,s,m,y){return {status:200,body:j(a,s,m,y)}}o.set("GET /form-types",async a=>{await u(a);let s=await r.getFormTypes();return p(s)}),o.set("GET /form-types/:id",async a=>(await u(a),p(await r.getFormType(a.params.id)))),o.set("POST /form-types",async a=>{await u(a);let s=z.parse(a.body);return p(await r.createFormType(s),201)}),o.set("PUT /form-types/:id",async a=>{await u(a);let s=_.parse(a.body);return p(await r.updateFormType(a.params.id,s))}),o.set("DELETE /form-types/:id",async a=>(await u(a),await r.deleteFormType(a.params.id),p(null,204))),o.set("GET /forms",async a=>{await u(a);let s=T.parse(a.query),{items:m,total:y}=await r.getFormDefinitions(s);return g(m,y,s.page,s.pageSize)}),o.set("GET /forms/:id",async a=>(await u(a),p(await r.getFormDefinition(a.params.id)))),o.set("GET /forms/:id/resolved",async a=>(await u(a),p(await r.getResolvedFormDefinition(a.params.id)))),o.set("POST /forms",async a=>{let s=await u(a),m=L.parse(a.body);return p(await r.createFormDefinition(m,s),201)}),o.set("PUT /forms/:id",async a=>{let s=await u(a),m=W.parse(a.body);return p(await r.updateFormDefinition(a.params.id,m,s))}),o.set("DELETE /forms/:id",async a=>(await u(a),await r.deleteFormDefinition(a.params.id),p(null,204))),o.set("GET /forms/:id/export",async a=>(await u(a),{status:200,body:await r.exportForm(a.params.id)})),o.set("POST /forms/import",async a=>{await u(a);let{json:s,tenantId:m}=a.body,y=await r.importForm(s,m);return p({formId:y},201)}),o.set("POST /forms/:formId/pages",async a=>{await u(a);let s=U.parse(a.body);return p(await r.createFormPage(a.params.formId,s),201)}),o.set("PUT /pages/:id",async a=>{await u(a);let s=K.parse(a.body);return p(await r.updateFormPage(a.params.id,s))}),o.set("DELETE /pages/:id",async a=>(await u(a),await r.deleteFormPage(a.params.id),p(null,204))),o.set("POST /pages/:pageId/rosters",async a=>{await u(a);let s=H.parse(a.body);return p(await r.createFormRoster(a.params.pageId,s),201)}),o.set("PUT /rosters/:id",async a=>{await u(a);let s=Z.parse(a.body);return p(await r.updateFormRoster(a.params.id,s))}),o.set("DELETE /rosters/:id",async a=>(await u(a),await r.deleteFormRoster(a.params.id),p(null,204))),o.set("POST /pages/:pageId/variables",async a=>{await u(a);let s=v.parse(a.body);return p(await r.createFormVariable({...s,pageId:a.params.pageId}),201)}),o.set("POST /rosters/:rosterId/variables",async a=>{await u(a);let s=v.parse(a.body);return p(await r.createFormVariable({...s,rosterId:a.params.rosterId}),201)}),o.set("PUT /variables/:id",async a=>{await u(a);let s=Q.parse(a.body);return p(await r.updateFormVariable(a.params.id,s))}),o.set("DELETE /variables/:id",async a=>(await u(a),await r.deleteFormVariable(a.params.id),p(null,204))),o.set("GET /forms/:formId/submissions",async a=>{await u(a);let s=T.parse(a.query),{items:m,total:y}=await r.getSubmissions({formId:a.params.formId,...s});return g(m,y,s.page,s.pageSize)}),o.set("GET /submissions/:id",async a=>(await u(a),p(await r.getSubmission(a.params.id)))),o.set("POST /submissions",async a=>{let s=await u(a),m=ee.parse(a.body);return p(await r.createSubmission(m,s),201)}),o.set("PUT /submissions/:id",async a=>{let s=await u(a),m=te.parse(a.body);return p(await r.updateSubmission(a.params.id,m,s))}),o.set("GET /scopes",async a=>{let s=await u(a),m=T.parse(a.query),{items:y,total:P}=await c.listScopes({tenantId:m.tenantId,page:m.page,pageSize:m.pageSize},s);return g(y,P,m.page,m.pageSize)}),o.set("GET /scopes/:id",async a=>(await u(a),p(await c.getScopeById(a.params.id)))),o.set("POST /scopes",async a=>{let s=await u(a),m=de.parse(a.body);return p(await c.createScope(m,s),201)}),o.set("PUT /scopes/:id",async a=>{let s=await u(a),m=ce.parse(a.body);return p(await c.updateScope(a.params.id,m,s))}),o.set("DELETE /scopes/:id",async a=>(await u(a),await c.deleteScope(a.params.id),p(null,204))),o.set("GET /scopes/:scopeId/templates",async a=>{await u(a);let s=T.parse(a.query),{items:m,total:y}=await c.listTemplates(a.params.scopeId,{page:s.page,pageSize:s.pageSize});return g(m,y,s.page,s.pageSize)}),o.set("POST /scopes/:scopeId/templates",async a=>{let s=await u(a),m=pe.parse(a.body);return p(await c.createTemplate(a.params.scopeId,m,s),201)}),o.set("GET /templates/:id",async a=>(await u(a),p(await c.getTemplateById(a.params.id)))),o.set("PUT /templates/:id",async a=>{let s=await u(a),m=me.parse(a.body);return p(await c.updateTemplate(a.params.id,m,s))}),o.set("DELETE /templates/:id",async a=>(await u(a),await c.deleteTemplate(a.params.id),p(null,204))),o.set("GET /scopes/:scopeId/datasources",async a=>{await u(a);let s=T.parse(a.query),{items:m,total:y}=await d.listDataSources(a.params.scopeId,{page:s.page,pageSize:s.pageSize});return g(m,y,s.page,s.pageSize)}),o.set("POST /scopes/:scopeId/datasources",async a=>{let s=await u(a),m=X.parse(a.body);return p(await d.createDataSource(a.params.scopeId,m,s),201)}),o.set("GET /datasources/:id",async a=>(await u(a),p(await d.getDataSourceById(a.params.id)))),o.set("PUT /datasources/:id",async a=>{let s=await u(a),m=le.parse(a.body);return p(await d.updateDataSource(a.params.id,m,s))}),o.set("DELETE /datasources/:id",async a=>(await u(a),await d.deleteDataSource(a.params.id),p(null,204))),o.set("GET /forms/:formId/datasources",async a=>{await u(a);let m=((await r.getFormDefinition(a.params.formId)).scopes??[]).map(M=>M.scopeId),{items:y,scopeHeaders:P}=await d.getDataSourcesByScopeIds(m);return p({items:y,scopeHeaders:P})});function R(a,s){for(let[m,y]of o){let[P,M]=m.split(" ");if(P!==a)continue;let ne=Ce(M,s);if(ne)return {handler:y,params:ne}}return null}return {routes:o,handle:async a=>{try{let s=R(a.method,a.path);return s?(a.params=s.params,await s.handler(a)):{status:404,body:{status:404,message:"Route not found",data:null}}}catch(s){return s instanceof l?{status:s.statusCode,body:{status:s.statusCode,message:s.message,data:null,errors:s.errors}}:s instanceof Error&&s.name==="ZodError"?{status:400,body:{status:400,message:"Validation error",data:null,errors:s.issues?.map(y=>y.message)}}:{status:500,body:{status:500,message:"Internal server error",data:null}}}}}}function Ce(i,e){let t=i.split("/").filter(Boolean),r=e.split("/").filter(Boolean);if(t.length!==r.length)return null;let c={};for(let d=0;d<t.length;d++){let o=t[d],u=r[d];if(o.startsWith(":"))c[o.slice(1)]=u;else if(o!==u)return null}return c}exports.ApiError=l;exports.FormService=C;exports.createFormDefinitionSchema=L;exports.createFormPageSchema=U;exports.createFormRosterSchema=H;exports.createFormRouter=ke;exports.createFormTypeSchema=z;exports.createFormVariableSchema=v;exports.createSubmissionSchema=ee;exports.noAuth=Y;exports.paginatedResponse=j;exports.paginationSchema=T;exports.successResponse=q;exports.updateFormDefinitionSchema=W;exports.updateFormPageSchema=K;exports.updateFormRosterSchema=Z;exports.updateFormTypeSchema=_;exports.updateFormVariableSchema=Q;exports.updateSubmissionSchema=te;//# sourceMappingURL=index.cjs.map
2
2
  //# sourceMappingURL=index.cjs.map