@shipfox/api-secrets 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 (288) hide show
  1. package/.turbo/turbo-build.log +2 -0
  2. package/.turbo/turbo-type$colon$emit.log +1 -0
  3. package/.turbo/turbo-type.log +1 -0
  4. package/CHANGELOG.md +116 -0
  5. package/LICENSE +21 -0
  6. package/README.md +207 -0
  7. package/dist/config.d.ts +8 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +38 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/core/crypto.d.ts +25 -0
  12. package/dist/core/crypto.d.ts.map +1 -0
  13. package/dist/core/crypto.js +85 -0
  14. package/dist/core/crypto.js.map +1 -0
  15. package/dist/core/dek-manager.d.ts +16 -0
  16. package/dist/core/dek-manager.d.ts.map +1 -0
  17. package/dist/core/dek-manager.js +85 -0
  18. package/dist/core/dek-manager.js.map +1 -0
  19. package/dist/core/errors.d.ts +53 -0
  20. package/dist/core/errors.d.ts.map +1 -0
  21. package/dist/core/errors.js +86 -0
  22. package/dist/core/errors.js.map +1 -0
  23. package/dist/core/fingerprint.d.ts +2 -0
  24. package/dist/core/fingerprint.d.ts.map +1 -0
  25. package/dist/core/fingerprint.js +9 -0
  26. package/dist/core/fingerprint.js.map +1 -0
  27. package/dist/core/index.d.ts +30 -0
  28. package/dist/core/index.d.ts.map +1 -0
  29. package/dist/core/index.js +97 -0
  30. package/dist/core/index.js.map +1 -0
  31. package/dist/core/key-provider.d.ts +17 -0
  32. package/dist/core/key-provider.d.ts.map +1 -0
  33. package/dist/core/key-provider.js +45 -0
  34. package/dist/core/key-provider.js.map +1 -0
  35. package/dist/core/local-secret-store.d.ts +19 -0
  36. package/dist/core/local-secret-store.d.ts.map +1 -0
  37. package/dist/core/local-secret-store.js +40 -0
  38. package/dist/core/local-secret-store.js.map +1 -0
  39. package/dist/core/management.d.ts +37 -0
  40. package/dist/core/management.d.ts.map +1 -0
  41. package/dist/core/management.js +403 -0
  42. package/dist/core/management.js.map +1 -0
  43. package/dist/core/rotate-kek.d.ts +10 -0
  44. package/dist/core/rotate-kek.d.ts.map +1 -0
  45. package/dist/core/rotate-kek.js +94 -0
  46. package/dist/core/rotate-kek.js.map +1 -0
  47. package/dist/core/secret-store.d.ts +33 -0
  48. package/dist/core/secret-store.d.ts.map +1 -0
  49. package/dist/core/secret-store.js +209 -0
  50. package/dist/core/secret-store.js.map +1 -0
  51. package/dist/core/store-resolver.d.ts +18 -0
  52. package/dist/core/store-resolver.d.ts.map +1 -0
  53. package/dist/core/store-resolver.js +10 -0
  54. package/dist/core/store-resolver.js.map +1 -0
  55. package/dist/core/store-validation.d.ts +11 -0
  56. package/dist/core/store-validation.d.ts.map +1 -0
  57. package/dist/core/store-validation.js +30 -0
  58. package/dist/core/store-validation.js.map +1 -0
  59. package/dist/core/value-cipher.d.ts +10 -0
  60. package/dist/core/value-cipher.d.ts.map +1 -0
  61. package/dist/core/value-cipher.js +22 -0
  62. package/dist/core/value-cipher.js.map +1 -0
  63. package/dist/core/variable-store.d.ts +24 -0
  64. package/dist/core/variable-store.d.ts.map +1 -0
  65. package/dist/core/variable-store.js +194 -0
  66. package/dist/core/variable-store.js.map +1 -0
  67. package/dist/db/cap.d.ts +8 -0
  68. package/dist/db/cap.d.ts.map +1 -0
  69. package/dist/db/cap.js +39 -0
  70. package/dist/db/cap.js.map +1 -0
  71. package/dist/db/data-keys.d.ts +24 -0
  72. package/dist/db/data-keys.d.ts.map +1 -0
  73. package/dist/db/data-keys.js +61 -0
  74. package/dist/db/data-keys.js.map +1 -0
  75. package/dist/db/db.d.ts +1254 -0
  76. package/dist/db/db.d.ts.map +1 -0
  77. package/dist/db/db.js +24 -0
  78. package/dist/db/db.js.map +1 -0
  79. package/dist/db/index.d.ts +13 -0
  80. package/dist/db/index.d.ts.map +1 -0
  81. package/dist/db/index.js +15 -0
  82. package/dist/db/index.js.map +1 -0
  83. package/dist/db/management.d.ts +50 -0
  84. package/dist/db/management.d.ts.map +1 -0
  85. package/dist/db/management.js +127 -0
  86. package/dist/db/management.js.map +1 -0
  87. package/dist/db/schema/common.d.ts +3 -0
  88. package/dist/db/schema/common.d.ts.map +1 -0
  89. package/dist/db/schema/common.js +8 -0
  90. package/dist/db/schema/common.js.map +1 -0
  91. package/dist/db/schema/data-keys.d.ts +103 -0
  92. package/dist/db/schema/data-keys.d.ts.map +1 -0
  93. package/dist/db/schema/data-keys.js +24 -0
  94. package/dist/db/schema/data-keys.js.map +1 -0
  95. package/dist/db/schema/outbox.d.ts +195 -0
  96. package/dist/db/schema/outbox.d.ts.map +1 -0
  97. package/dist/db/schema/outbox.js +5 -0
  98. package/dist/db/schema/outbox.js.map +1 -0
  99. package/dist/db/schema/values.d.ts +193 -0
  100. package/dist/db/schema/values.d.ts.map +1 -0
  101. package/dist/db/schema/values.js +43 -0
  102. package/dist/db/schema/values.js.map +1 -0
  103. package/dist/db/schema/variables.d.ts +175 -0
  104. package/dist/db/schema/variables.d.ts.map +1 -0
  105. package/dist/db/schema/variables.js +41 -0
  106. package/dist/db/schema/variables.js.map +1 -0
  107. package/dist/db/scope.d.ts +20 -0
  108. package/dist/db/scope.d.ts.map +1 -0
  109. package/dist/db/scope.js +19 -0
  110. package/dist/db/scope.js.map +1 -0
  111. package/dist/db/values.d.ts +33 -0
  112. package/dist/db/values.d.ts.map +1 -0
  113. package/dist/db/values.js +119 -0
  114. package/dist/db/values.js.map +1 -0
  115. package/dist/db/variables.d.ts +32 -0
  116. package/dist/db/variables.d.ts.map +1 -0
  117. package/dist/db/variables.js +117 -0
  118. package/dist/db/variables.js.map +1 -0
  119. package/dist/index.d.ts +4 -0
  120. package/dist/index.d.ts.map +1 -0
  121. package/dist/index.js +28 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/metrics/index.d.ts +3 -0
  124. package/dist/metrics/index.d.ts.map +1 -0
  125. package/dist/metrics/index.js +4 -0
  126. package/dist/metrics/index.js.map +1 -0
  127. package/dist/metrics/instance.d.ts +39 -0
  128. package/dist/metrics/instance.d.ts.map +1 -0
  129. package/dist/metrics/instance.js +151 -0
  130. package/dist/metrics/instance.js.map +1 -0
  131. package/dist/metrics/service.d.ts +2 -0
  132. package/dist/metrics/service.d.ts.map +1 -0
  133. package/dist/metrics/service.js +21 -0
  134. package/dist/metrics/service.js.map +1 -0
  135. package/dist/presentation/dto/index.d.ts +2 -0
  136. package/dist/presentation/dto/index.d.ts.map +1 -0
  137. package/dist/presentation/dto/index.js +3 -0
  138. package/dist/presentation/dto/index.js.map +1 -0
  139. package/dist/presentation/dto/management.d.ts +7 -0
  140. package/dist/presentation/dto/management.d.ts.map +1 -0
  141. package/dist/presentation/dto/management.js +32 -0
  142. package/dist/presentation/dto/management.js.map +1 -0
  143. package/dist/presentation/e2eRoutes/create-secret.d.ts +2 -0
  144. package/dist/presentation/e2eRoutes/create-secret.d.ts.map +1 -0
  145. package/dist/presentation/e2eRoutes/create-secret.js +34 -0
  146. package/dist/presentation/e2eRoutes/create-secret.js.map +1 -0
  147. package/dist/presentation/e2eRoutes/create-variable.d.ts +2 -0
  148. package/dist/presentation/e2eRoutes/create-variable.d.ts.map +1 -0
  149. package/dist/presentation/e2eRoutes/create-variable.js +34 -0
  150. package/dist/presentation/e2eRoutes/create-variable.js.map +1 -0
  151. package/dist/presentation/e2eRoutes/index.d.ts +3 -0
  152. package/dist/presentation/e2eRoutes/index.d.ts.map +1 -0
  153. package/dist/presentation/e2eRoutes/index.js +11 -0
  154. package/dist/presentation/e2eRoutes/index.js.map +1 -0
  155. package/dist/presentation/routes/auth.d.ts +16 -0
  156. package/dist/presentation/routes/auth.d.ts.map +1 -0
  157. package/dist/presentation/routes/auth.js +42 -0
  158. package/dist/presentation/routes/auth.js.map +1 -0
  159. package/dist/presentation/routes/batch-secrets.d.ts +2 -0
  160. package/dist/presentation/routes/batch-secrets.d.ts.map +1 -0
  161. package/dist/presentation/routes/batch-secrets.js +44 -0
  162. package/dist/presentation/routes/batch-secrets.js.map +1 -0
  163. package/dist/presentation/routes/batch-variables.d.ts +2 -0
  164. package/dist/presentation/routes/batch-variables.d.ts.map +1 -0
  165. package/dist/presentation/routes/batch-variables.js +44 -0
  166. package/dist/presentation/routes/batch-variables.js.map +1 -0
  167. package/dist/presentation/routes/cursor.d.ts +3 -0
  168. package/dist/presentation/routes/cursor.d.ts.map +1 -0
  169. package/dist/presentation/routes/cursor.js +19 -0
  170. package/dist/presentation/routes/cursor.js.map +1 -0
  171. package/dist/presentation/routes/delete-secret.d.ts +2 -0
  172. package/dist/presentation/routes/delete-secret.d.ts.map +1 -0
  173. package/dist/presentation/routes/delete-secret.js +40 -0
  174. package/dist/presentation/routes/delete-secret.js.map +1 -0
  175. package/dist/presentation/routes/delete-variable.d.ts +2 -0
  176. package/dist/presentation/routes/delete-variable.d.ts.map +1 -0
  177. package/dist/presentation/routes/delete-variable.js +40 -0
  178. package/dist/presentation/routes/delete-variable.js.map +1 -0
  179. package/dist/presentation/routes/errors.d.ts +2 -0
  180. package/dist/presentation/routes/errors.d.ts.map +1 -0
  181. package/dist/presentation/routes/errors.js +73 -0
  182. package/dist/presentation/routes/errors.js.map +1 -0
  183. package/dist/presentation/routes/get-variable.d.ts +2 -0
  184. package/dist/presentation/routes/get-variable.d.ts.map +1 -0
  185. package/dist/presentation/routes/get-variable.js +42 -0
  186. package/dist/presentation/routes/get-variable.js.map +1 -0
  187. package/dist/presentation/routes/index.d.ts +3 -0
  188. package/dist/presentation/routes/index.d.ts.map +1 -0
  189. package/dist/presentation/routes/index.js +29 -0
  190. package/dist/presentation/routes/index.js.map +1 -0
  191. package/dist/presentation/routes/list-secrets.d.ts +2 -0
  192. package/dist/presentation/routes/list-secrets.d.ts.map +1 -0
  193. package/dist/presentation/routes/list-secrets.js +50 -0
  194. package/dist/presentation/routes/list-secrets.js.map +1 -0
  195. package/dist/presentation/routes/list-variables.d.ts +2 -0
  196. package/dist/presentation/routes/list-variables.d.ts.map +1 -0
  197. package/dist/presentation/routes/list-variables.js +50 -0
  198. package/dist/presentation/routes/list-variables.js.map +1 -0
  199. package/dist/presentation/routes/put-secret.d.ts +2 -0
  200. package/dist/presentation/routes/put-secret.d.ts.map +1 -0
  201. package/dist/presentation/routes/put-secret.js +52 -0
  202. package/dist/presentation/routes/put-secret.js.map +1 -0
  203. package/dist/presentation/routes/put-variable.d.ts +2 -0
  204. package/dist/presentation/routes/put-variable.d.ts.map +1 -0
  205. package/dist/presentation/routes/put-variable.js +52 -0
  206. package/dist/presentation/routes/put-variable.js.map +1 -0
  207. package/dist/presentation/routes/warnings.d.ts +5 -0
  208. package/dist/presentation/routes/warnings.d.ts.map +1 -0
  209. package/dist/presentation/routes/warnings.js +16 -0
  210. package/dist/presentation/routes/warnings.js.map +1 -0
  211. package/dist/tsconfig.test.tsbuildinfo +1 -0
  212. package/drizzle/0000_lowly_ogun.sql +59 -0
  213. package/drizzle/meta/0000_snapshot.json +547 -0
  214. package/drizzle/meta/_journal.json +13 -0
  215. package/drizzle.config.ts +7 -0
  216. package/package.json +77 -0
  217. package/src/config.test.ts +41 -0
  218. package/src/config.ts +41 -0
  219. package/src/core/crypto.test.ts +115 -0
  220. package/src/core/crypto.ts +105 -0
  221. package/src/core/dek-manager.test.ts +120 -0
  222. package/src/core/dek-manager.ts +98 -0
  223. package/src/core/errors.ts +100 -0
  224. package/src/core/fingerprint.test.ts +27 -0
  225. package/src/core/fingerprint.ts +14 -0
  226. package/src/core/index.ts +153 -0
  227. package/src/core/key-provider.test.ts +44 -0
  228. package/src/core/key-provider.ts +70 -0
  229. package/src/core/local-secret-store.ts +49 -0
  230. package/src/core/management.test.ts +37 -0
  231. package/src/core/management.ts +503 -0
  232. package/src/core/rotate-kek.test.ts +183 -0
  233. package/src/core/rotate-kek.ts +100 -0
  234. package/src/core/secret-store.test.ts +301 -0
  235. package/src/core/secret-store.ts +251 -0
  236. package/src/core/store-resolver.test.ts +20 -0
  237. package/src/core/store-resolver.ts +28 -0
  238. package/src/core/store-validation.ts +43 -0
  239. package/src/core/value-cipher.ts +26 -0
  240. package/src/core/variable-store.test.ts +106 -0
  241. package/src/core/variable-store.ts +232 -0
  242. package/src/db/cap.ts +58 -0
  243. package/src/db/data-keys.ts +99 -0
  244. package/src/db/db.ts +26 -0
  245. package/src/db/index.ts +45 -0
  246. package/src/db/management.ts +252 -0
  247. package/src/db/schema/common.ts +8 -0
  248. package/src/db/schema/data-keys.ts +31 -0
  249. package/src/db/schema/outbox.ts +4 -0
  250. package/src/db/schema/values.ts +74 -0
  251. package/src/db/schema/variables.ts +71 -0
  252. package/src/db/scope.ts +42 -0
  253. package/src/db/values.ts +191 -0
  254. package/src/db/variables.ts +187 -0
  255. package/src/index.test.ts +11 -0
  256. package/src/index.ts +50 -0
  257. package/src/metrics/index.ts +19 -0
  258. package/src/metrics/instance.ts +219 -0
  259. package/src/metrics/service.ts +19 -0
  260. package/src/presentation/dto/index.ts +1 -0
  261. package/src/presentation/dto/management.ts +36 -0
  262. package/src/presentation/e2eRoutes/create-secret.ts +31 -0
  263. package/src/presentation/e2eRoutes/create-variable.ts +34 -0
  264. package/src/presentation/e2eRoutes/index.test.ts +94 -0
  265. package/src/presentation/e2eRoutes/index.ts +8 -0
  266. package/src/presentation/routes/auth.ts +50 -0
  267. package/src/presentation/routes/batch-secrets.ts +33 -0
  268. package/src/presentation/routes/batch-variables.ts +33 -0
  269. package/src/presentation/routes/cursor.ts +23 -0
  270. package/src/presentation/routes/delete-secret.ts +26 -0
  271. package/src/presentation/routes/delete-variable.ts +26 -0
  272. package/src/presentation/routes/errors.ts +63 -0
  273. package/src/presentation/routes/get-variable.ts +32 -0
  274. package/src/presentation/routes/index.ts +29 -0
  275. package/src/presentation/routes/list-secrets.ts +41 -0
  276. package/src/presentation/routes/list-variables.ts +41 -0
  277. package/src/presentation/routes/management.test.ts +452 -0
  278. package/src/presentation/routes/put-secret.ts +39 -0
  279. package/src/presentation/routes/put-variable.ts +39 -0
  280. package/src/presentation/routes/warnings.ts +23 -0
  281. package/test/env.ts +8 -0
  282. package/test/globalSetup.ts +18 -0
  283. package/test/setup.ts +17 -0
  284. package/tsconfig.build.json +10 -0
  285. package/tsconfig.build.tsbuildinfo +1 -0
  286. package/tsconfig.json +7 -0
  287. package/tsconfig.test.json +8 -0
  288. package/vitest.config.ts +12 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/db/schema/variables.ts"],"sourcesContent":["import {NAMESPACE_PATTERN_SOURCE, SECRET_KEY_PATTERN_SOURCE} from '@shipfox/api-secrets-dto';\nimport {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {sql} from 'drizzle-orm';\nimport {check, index, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport {pgTable, sqlStringLiteral} from './common.js';\n\nexport interface SecretVariable {\n id: string;\n workspaceId: string;\n projectId: string | null;\n namespace: string;\n key: string;\n value: string;\n createdAt: Date;\n updatedAt: Date;\n lastEditedBy: string | null;\n}\n\nexport const secretVariables = pgTable(\n 'variables',\n {\n id: uuidv7PrimaryKey(),\n workspaceId: uuid('workspace_id').notNull(),\n projectId: uuid('project_id'),\n namespace: text('namespace').notNull(),\n key: text('key').notNull(),\n value: text('value').notNull(),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n lastEditedBy: uuid('last_edited_by'),\n },\n (table) => [\n uniqueIndex('secrets_variables_ws_scope_unique')\n .on(table.workspaceId, table.namespace, table.key)\n .where(sql`\"project_id\" IS NULL`),\n uniqueIndex('secrets_variables_project_scope_unique')\n .on(table.workspaceId, table.projectId, table.namespace, table.key)\n .where(sql`\"project_id\" IS NOT NULL`),\n index('secrets_variables_lookup_idx').on(\n table.workspaceId,\n table.namespace,\n table.projectId,\n table.key,\n ),\n check(\n 'secrets_variables_key_ck',\n sql`${table.key} ~ ${sqlStringLiteral(SECRET_KEY_PATTERN_SOURCE)}`,\n ),\n check(\n 'secrets_variables_namespace_ck',\n sql`char_length(${table.namespace}) <= 128 AND (${table.namespace} = '' OR ${table.namespace} ~ ${sqlStringLiteral(NAMESPACE_PATTERN_SOURCE)})`,\n ),\n ],\n);\n\nexport type SecretVariableDb = typeof secretVariables.$inferSelect;\nexport type SecretVariableCreateDb = typeof secretVariables.$inferInsert;\n\nexport function toSecretVariable(row: SecretVariableDb): SecretVariable {\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n projectId: row.projectId,\n namespace: row.namespace,\n key: row.key,\n value: row.value,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n lastEditedBy: row.lastEditedBy,\n };\n}\n"],"names":["NAMESPACE_PATTERN_SOURCE","SECRET_KEY_PATTERN_SOURCE","uuidv7PrimaryKey","sql","check","index","text","timestamp","uniqueIndex","uuid","pgTable","sqlStringLiteral","secretVariables","id","workspaceId","notNull","projectId","namespace","key","value","createdAt","withTimezone","defaultNow","updatedAt","lastEditedBy","table","on","where","toSecretVariable","row"],"mappings":"AAAA,SAAQA,wBAAwB,EAAEC,yBAAyB,QAAO,2BAA2B;AAC7F,SAAQC,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,GAAG,QAAO,cAAc;AAChC,SAAQC,KAAK,EAAEC,KAAK,EAAEC,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEC,IAAI,QAAO,sBAAsB;AACrF,SAAQC,OAAO,EAAEC,gBAAgB,QAAO,cAAc;AActD,OAAO,MAAMC,kBAAkBF,QAC7B,aACA;IACEG,IAAIX;IACJY,aAAaL,KAAK,gBAAgBM,OAAO;IACzCC,WAAWP,KAAK;IAChBQ,WAAWX,KAAK,aAAaS,OAAO;IACpCG,KAAKZ,KAAK,OAAOS,OAAO;IACxBI,OAAOb,KAAK,SAASS,OAAO;IAC5BK,WAAWb,UAAU,cAAc;QAACc,cAAc;IAAI,GAAGN,OAAO,GAAGO,UAAU;IAC7EC,WAAWhB,UAAU,cAAc;QAACc,cAAc;IAAI,GAAGN,OAAO,GAAGO,UAAU;IAC7EE,cAAcf,KAAK;AACrB,GACA,CAACgB,QAAU;QACTjB,YAAY,qCACTkB,EAAE,CAACD,MAAMX,WAAW,EAAEW,MAAMR,SAAS,EAAEQ,MAAMP,GAAG,EAChDS,KAAK,CAACxB,GAAG,CAAC,oBAAoB,CAAC;QAClCK,YAAY,0CACTkB,EAAE,CAACD,MAAMX,WAAW,EAAEW,MAAMT,SAAS,EAAES,MAAMR,SAAS,EAAEQ,MAAMP,GAAG,EACjES,KAAK,CAACxB,GAAG,CAAC,wBAAwB,CAAC;QACtCE,MAAM,gCAAgCqB,EAAE,CACtCD,MAAMX,WAAW,EACjBW,MAAMR,SAAS,EACfQ,MAAMT,SAAS,EACfS,MAAMP,GAAG;QAEXd,MACE,4BACAD,GAAG,CAAC,EAAEsB,MAAMP,GAAG,CAAC,GAAG,EAAEP,iBAAiBV,2BAA2B,CAAC;QAEpEG,MACE,kCACAD,GAAG,CAAC,YAAY,EAAEsB,MAAMR,SAAS,CAAC,cAAc,EAAEQ,MAAMR,SAAS,CAAC,SAAS,EAAEQ,MAAMR,SAAS,CAAC,GAAG,EAAEN,iBAAiBX,0BAA0B,CAAC,CAAC;KAElJ,EACD;AAKF,OAAO,SAAS4B,iBAAiBC,GAAqB;IACpD,OAAO;QACLhB,IAAIgB,IAAIhB,EAAE;QACVC,aAAae,IAAIf,WAAW;QAC5BE,WAAWa,IAAIb,SAAS;QACxBC,WAAWY,IAAIZ,SAAS;QACxBC,KAAKW,IAAIX,GAAG;QACZC,OAAOU,IAAIV,KAAK;QAChBC,WAAWS,IAAIT,SAAS;QACxBG,WAAWM,IAAIN,SAAS;QACxBC,cAAcK,IAAIL,YAAY;IAChC;AACF"}
@@ -0,0 +1,20 @@
1
+ import { type SQL } from 'drizzle-orm';
2
+ import type { PgColumn } from 'drizzle-orm/pg-core';
3
+ export interface StoreScope {
4
+ projectId?: string | null | undefined;
5
+ }
6
+ export interface ScopeColumns {
7
+ workspaceId: PgColumn;
8
+ projectId: PgColumn;
9
+ namespace: PgColumn;
10
+ key: PgColumn;
11
+ }
12
+ export declare function normalizedProjectId(scope?: StoreScope | undefined): string | null;
13
+ export declare function scopeConflictTargetWhere(scope?: StoreScope | undefined): SQL;
14
+ export declare function scopeExactWhere(columns: ScopeColumns, params: StoreScope): SQL | undefined;
15
+ export declare function lookupWithPrecedenceWhere(columns: ScopeColumns, params: StoreScope & {
16
+ workspaceId: string;
17
+ namespace: string;
18
+ key: string;
19
+ }): SQL | undefined;
20
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/db/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,GAAG,EAAM,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAElD,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,QAAQ,CAAC;IACtB,SAAS,EAAE,QAAQ,CAAC;IACpB,SAAS,EAAE,QAAQ,CAAC;IACpB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAEjF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,GAAG,CAI5E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,GAAG,GAAG,SAAS,CAG1F;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,UAAU,GAAG;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,GACzE,GAAG,GAAG,SAAS,CASjB"}
@@ -0,0 +1,19 @@
1
+ import { and, eq, isNull, or, sql } from 'drizzle-orm';
2
+ export function normalizedProjectId(scope) {
3
+ return scope?.projectId || null;
4
+ }
5
+ export function scopeConflictTargetWhere(scope) {
6
+ return normalizedProjectId(scope) !== null ? sql`"project_id" IS NOT NULL` : sql`"project_id" IS NULL`;
7
+ }
8
+ export function scopeExactWhere(columns, params) {
9
+ const projectId = normalizedProjectId(params);
10
+ return projectId !== null ? eq(columns.projectId, projectId) : isNull(columns.projectId);
11
+ }
12
+ export function lookupWithPrecedenceWhere(columns, params) {
13
+ const base = and(eq(columns.workspaceId, params.workspaceId), eq(columns.namespace, params.namespace), eq(columns.key, params.key));
14
+ const projectId = normalizedProjectId(params);
15
+ if (projectId === null) return and(base, isNull(columns.projectId));
16
+ return and(base, or(eq(columns.projectId, projectId), isNull(columns.projectId)));
17
+ }
18
+
19
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/db/scope.ts"],"sourcesContent":["import {and, eq, isNull, or, type SQL, sql} from 'drizzle-orm';\nimport type {PgColumn} from 'drizzle-orm/pg-core';\n\nexport interface StoreScope {\n projectId?: string | null | undefined;\n}\n\nexport interface ScopeColumns {\n workspaceId: PgColumn;\n projectId: PgColumn;\n namespace: PgColumn;\n key: PgColumn;\n}\n\nexport function normalizedProjectId(scope?: StoreScope | undefined): string | null {\n return scope?.projectId || null;\n}\n\nexport function scopeConflictTargetWhere(scope?: StoreScope | undefined): SQL {\n return normalizedProjectId(scope) !== null\n ? sql`\"project_id\" IS NOT NULL`\n : sql`\"project_id\" IS NULL`;\n}\n\nexport function scopeExactWhere(columns: ScopeColumns, params: StoreScope): SQL | undefined {\n const projectId = normalizedProjectId(params);\n return projectId !== null ? eq(columns.projectId, projectId) : isNull(columns.projectId);\n}\n\nexport function lookupWithPrecedenceWhere(\n columns: ScopeColumns,\n params: StoreScope & {workspaceId: string; namespace: string; key: string},\n): SQL | undefined {\n const base = and(\n eq(columns.workspaceId, params.workspaceId),\n eq(columns.namespace, params.namespace),\n eq(columns.key, params.key),\n );\n const projectId = normalizedProjectId(params);\n if (projectId === null) return and(base, isNull(columns.projectId));\n return and(base, or(eq(columns.projectId, projectId), isNull(columns.projectId)));\n}\n"],"names":["and","eq","isNull","or","sql","normalizedProjectId","scope","projectId","scopeConflictTargetWhere","scopeExactWhere","columns","params","lookupWithPrecedenceWhere","base","workspaceId","namespace","key"],"mappings":"AAAA,SAAQA,GAAG,EAAEC,EAAE,EAAEC,MAAM,EAAEC,EAAE,EAAYC,GAAG,QAAO,cAAc;AAc/D,OAAO,SAASC,oBAAoBC,KAA8B;IAChE,OAAOA,OAAOC,aAAa;AAC7B;AAEA,OAAO,SAASC,yBAAyBF,KAA8B;IACrE,OAAOD,oBAAoBC,WAAW,OAClCF,GAAG,CAAC,wBAAwB,CAAC,GAC7BA,GAAG,CAAC,oBAAoB,CAAC;AAC/B;AAEA,OAAO,SAASK,gBAAgBC,OAAqB,EAAEC,MAAkB;IACvE,MAAMJ,YAAYF,oBAAoBM;IACtC,OAAOJ,cAAc,OAAON,GAAGS,QAAQH,SAAS,EAAEA,aAAaL,OAAOQ,QAAQH,SAAS;AACzF;AAEA,OAAO,SAASK,0BACdF,OAAqB,EACrBC,MAA0E;IAE1E,MAAME,OAAOb,IACXC,GAAGS,QAAQI,WAAW,EAAEH,OAAOG,WAAW,GAC1Cb,GAAGS,QAAQK,SAAS,EAAEJ,OAAOI,SAAS,GACtCd,GAAGS,QAAQM,GAAG,EAAEL,OAAOK,GAAG;IAE5B,MAAMT,YAAYF,oBAAoBM;IACtC,IAAIJ,cAAc,MAAM,OAAOP,IAAIa,MAAMX,OAAOQ,QAAQH,SAAS;IACjE,OAAOP,IAAIa,MAAMV,GAAGF,GAAGS,QAAQH,SAAS,EAAEA,YAAYL,OAAOQ,QAAQH,SAAS;AAChF"}
@@ -0,0 +1,33 @@
1
+ import { type Tx } from './db.js';
2
+ import { type SecretValue } from './schema/values.js';
3
+ import { type StoreScope } from './scope.js';
4
+ export interface SecretValueWrite {
5
+ workspaceId: string;
6
+ projectId: string | null;
7
+ namespace: string;
8
+ key: string;
9
+ ciphertext: string;
10
+ fingerprint: string | null;
11
+ lastEditedBy?: string | null | undefined;
12
+ }
13
+ export declare function getSecretValueRowWithPrecedence(params: StoreScope & {
14
+ workspaceId: string;
15
+ namespace: string;
16
+ key: string;
17
+ }, tx?: Tx): Promise<SecretValue | undefined>;
18
+ export declare function listSecretValueRowsByNamespace(params: StoreScope & {
19
+ workspaceId: string;
20
+ namespace: string;
21
+ }, tx?: Tx): Promise<SecretValue[]>;
22
+ export declare function upsertSecretValueRows(rows: SecretValueWrite[], tx: Tx): Promise<void>;
23
+ export declare function countSecretValueRows(params: StoreScope & {
24
+ workspaceId: string;
25
+ namespace: string;
26
+ keys: string[];
27
+ }, tx: Tx): Promise<number>;
28
+ export declare function deleteSecretValueRows(params: StoreScope & {
29
+ workspaceId: string;
30
+ namespace: string;
31
+ keys?: string[] | undefined;
32
+ }, tx?: Tx): Promise<number>;
33
+ //# sourceMappingURL=values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../src/db/values.ts"],"names":[],"mappings":"AAEA,OAAO,EAAK,KAAK,EAAE,EAAC,MAAM,SAAS,CAAC;AACpC,OAAO,EAAC,KAAK,WAAW,EAA8B,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAGL,KAAK,UAAU,EAGhB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC1C;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,UAAU,GAAG;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,EAC1E,EAAE,CAAC,EAAE,EAAE,GACN,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAoBlC;AAED,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,UAAU,GAAG;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,EAC7D,EAAE,CAAC,EAAE,EAAE,GACN,OAAO,CAAC,WAAW,EAAE,CAAC,CAWxB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB3F;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,UAAU,GAAG;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAC,EAC7E,EAAE,EAAE,EAAE,GACL,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,UAAU,GAAG;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;CAAC,EAC1F,EAAE,CAAC,EAAE,EAAE,GACN,OAAO,CAAC,MAAM,CAAC,CAyBjB"}
@@ -0,0 +1,119 @@
1
+ import { and, eq, inArray, isNull, sql } from 'drizzle-orm';
2
+ import { SecretBatchScopeMismatchError } from '#core/errors.js';
3
+ import { db } from './db.js';
4
+ import { secretValues, toSecretValue } from './schema/values.js';
5
+ import { lookupWithPrecedenceWhere, normalizedProjectId, scopeConflictTargetWhere, scopeExactWhere } from './scope.js';
6
+ export async function getSecretValueRowWithPrecedence(params, tx) {
7
+ const executor = tx ?? db();
8
+ const rows = await executor.select().from(secretValues).where(lookupWithPrecedenceWhere({
9
+ workspaceId: secretValues.workspaceId,
10
+ projectId: secretValues.projectId,
11
+ namespace: secretValues.namespace,
12
+ key: secretValues.key
13
+ }, params)).orderBy(sql`${secretValues.projectId} NULLS LAST`).limit(1);
14
+ const row = rows[0];
15
+ return row ? toSecretValue(row) : undefined;
16
+ }
17
+ export async function listSecretValueRowsByNamespace(params, tx) {
18
+ const executor = tx ?? db();
19
+ const rows = await executor.execute(sql`
20
+ SELECT DISTINCT ON (key)
21
+ id, workspace_id, project_id, namespace, key, ciphertext, fingerprint,
22
+ created_at, updated_at, last_edited_by
23
+ FROM secrets_values
24
+ WHERE ${listByNamespaceSql(params)}
25
+ ORDER BY key, project_id NULLS LAST, id
26
+ `);
27
+ return rows.rows.map(rowToSecretValue);
28
+ }
29
+ export async function upsertSecretValueRows(rows, tx) {
30
+ if (rows.length === 0) return;
31
+ const projectId = batchProjectId(rows);
32
+ await tx.insert(secretValues).values(rows).onConflictDoUpdate({
33
+ target: projectId ? [
34
+ secretValues.workspaceId,
35
+ secretValues.projectId,
36
+ secretValues.namespace,
37
+ secretValues.key
38
+ ] : [
39
+ secretValues.workspaceId,
40
+ secretValues.namespace,
41
+ secretValues.key
42
+ ],
43
+ targetWhere: scopeConflictTargetWhere({
44
+ projectId
45
+ }),
46
+ set: {
47
+ ciphertext: sql`excluded.ciphertext`,
48
+ fingerprint: sql`excluded.fingerprint`,
49
+ lastEditedBy: sql`excluded.last_edited_by`,
50
+ updatedAt: sql`NOW()`
51
+ }
52
+ });
53
+ }
54
+ export async function countSecretValueRows(params, tx) {
55
+ if (params.keys.length === 0) return 0;
56
+ const rows = await tx.select({
57
+ count: sql`COUNT(*)`
58
+ }).from(secretValues).where(and(eq(secretValues.workspaceId, params.workspaceId), eq(secretValues.namespace, params.namespace), scopeExactWhere({
59
+ workspaceId: secretValues.workspaceId,
60
+ projectId: secretValues.projectId,
61
+ namespace: secretValues.namespace,
62
+ key: secretValues.key
63
+ }, params) ?? isNull(secretValues.projectId), inArray(secretValues.key, params.keys)));
64
+ return Number(rows[0]?.count ?? 0);
65
+ }
66
+ export async function deleteSecretValueRows(params, tx) {
67
+ if (params.keys && params.keys.length === 0) return 0;
68
+ const executor = tx ?? db();
69
+ const filters = [
70
+ eq(secretValues.workspaceId, params.workspaceId),
71
+ eq(secretValues.namespace, params.namespace),
72
+ scopeExactWhere({
73
+ workspaceId: secretValues.workspaceId,
74
+ projectId: secretValues.projectId,
75
+ namespace: secretValues.namespace,
76
+ key: secretValues.key
77
+ }, params) ?? isNull(secretValues.projectId)
78
+ ];
79
+ if (params.keys && params.keys.length > 0) {
80
+ filters.push(inArray(secretValues.key, params.keys));
81
+ }
82
+ const deleted = await executor.delete(secretValues).where(and(...filters)).returning({
83
+ id: secretValues.id
84
+ });
85
+ return deleted.length;
86
+ }
87
+ function batchProjectId(rows) {
88
+ const projectId = normalizedProjectId({
89
+ projectId: rows[0]?.projectId
90
+ });
91
+ const mixedScope = rows.some((row)=>normalizedProjectId({
92
+ projectId: row.projectId
93
+ }) !== projectId);
94
+ if (mixedScope) throw new SecretBatchScopeMismatchError();
95
+ return projectId;
96
+ }
97
+ function listByNamespaceSql(params) {
98
+ const projectId = normalizedProjectId(params);
99
+ if (!projectId) {
100
+ return sql`workspace_id = ${params.workspaceId} AND namespace = ${params.namespace} AND project_id IS NULL`;
101
+ }
102
+ return sql`workspace_id = ${params.workspaceId} AND namespace = ${params.namespace} AND (project_id = ${projectId} OR project_id IS NULL)`;
103
+ }
104
+ function rowToSecretValue(row) {
105
+ return {
106
+ id: row.id,
107
+ workspaceId: row.workspace_id,
108
+ projectId: row.project_id,
109
+ namespace: row.namespace,
110
+ key: row.key,
111
+ ciphertext: row.ciphertext,
112
+ fingerprint: row.fingerprint,
113
+ createdAt: row.created_at,
114
+ updatedAt: row.updated_at,
115
+ lastEditedBy: row.last_edited_by
116
+ };
117
+ }
118
+
119
+ //# sourceMappingURL=values.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/db/values.ts"],"sourcesContent":["import {and, eq, inArray, isNull, sql} from 'drizzle-orm';\nimport {SecretBatchScopeMismatchError} from '#core/errors.js';\nimport {db, type Tx} from './db.js';\nimport {type SecretValue, secretValues, toSecretValue} from './schema/values.js';\nimport {\n lookupWithPrecedenceWhere,\n normalizedProjectId,\n type StoreScope,\n scopeConflictTargetWhere,\n scopeExactWhere,\n} from './scope.js';\n\nexport interface SecretValueWrite {\n workspaceId: string;\n projectId: string | null;\n namespace: string;\n key: string;\n ciphertext: string;\n fingerprint: string | null;\n lastEditedBy?: string | null | undefined;\n}\n\nexport async function getSecretValueRowWithPrecedence(\n params: StoreScope & {workspaceId: string; namespace: string; key: string},\n tx?: Tx,\n): Promise<SecretValue | undefined> {\n const executor = tx ?? db();\n const rows = await executor\n .select()\n .from(secretValues)\n .where(\n lookupWithPrecedenceWhere(\n {\n workspaceId: secretValues.workspaceId,\n projectId: secretValues.projectId,\n namespace: secretValues.namespace,\n key: secretValues.key,\n },\n params,\n ),\n )\n .orderBy(sql`${secretValues.projectId} NULLS LAST`)\n .limit(1);\n const row = rows[0];\n return row ? toSecretValue(row) : undefined;\n}\n\nexport async function listSecretValueRowsByNamespace(\n params: StoreScope & {workspaceId: string; namespace: string},\n tx?: Tx,\n): Promise<SecretValue[]> {\n const executor = tx ?? db();\n const rows = await executor.execute<SecretValueRow>(sql`\n SELECT DISTINCT ON (key)\n id, workspace_id, project_id, namespace, key, ciphertext, fingerprint,\n created_at, updated_at, last_edited_by\n FROM secrets_values\n WHERE ${listByNamespaceSql(params)}\n ORDER BY key, project_id NULLS LAST, id\n `);\n return rows.rows.map(rowToSecretValue);\n}\n\nexport async function upsertSecretValueRows(rows: SecretValueWrite[], tx: Tx): Promise<void> {\n if (rows.length === 0) return;\n const projectId = batchProjectId(rows);\n await tx\n .insert(secretValues)\n .values(rows)\n .onConflictDoUpdate({\n target: projectId\n ? [\n secretValues.workspaceId,\n secretValues.projectId,\n secretValues.namespace,\n secretValues.key,\n ]\n : [secretValues.workspaceId, secretValues.namespace, secretValues.key],\n targetWhere: scopeConflictTargetWhere({projectId}),\n set: {\n ciphertext: sql`excluded.ciphertext`,\n fingerprint: sql`excluded.fingerprint`,\n lastEditedBy: sql`excluded.last_edited_by`,\n updatedAt: sql`NOW()`,\n },\n });\n}\n\nexport async function countSecretValueRows(\n params: StoreScope & {workspaceId: string; namespace: string; keys: string[]},\n tx: Tx,\n): Promise<number> {\n if (params.keys.length === 0) return 0;\n\n const rows = await tx\n .select({count: sql<string | number>`COUNT(*)`})\n .from(secretValues)\n .where(\n and(\n eq(secretValues.workspaceId, params.workspaceId),\n eq(secretValues.namespace, params.namespace),\n scopeExactWhere(\n {\n workspaceId: secretValues.workspaceId,\n projectId: secretValues.projectId,\n namespace: secretValues.namespace,\n key: secretValues.key,\n },\n params,\n ) ?? isNull(secretValues.projectId),\n inArray(secretValues.key, params.keys),\n ),\n );\n\n return Number(rows[0]?.count ?? 0);\n}\n\nexport async function deleteSecretValueRows(\n params: StoreScope & {workspaceId: string; namespace: string; keys?: string[] | undefined},\n tx?: Tx,\n): Promise<number> {\n if (params.keys && params.keys.length === 0) return 0;\n\n const executor = tx ?? db();\n const filters = [\n eq(secretValues.workspaceId, params.workspaceId),\n eq(secretValues.namespace, params.namespace),\n scopeExactWhere(\n {\n workspaceId: secretValues.workspaceId,\n projectId: secretValues.projectId,\n namespace: secretValues.namespace,\n key: secretValues.key,\n },\n params,\n ) ?? isNull(secretValues.projectId),\n ];\n if (params.keys && params.keys.length > 0) {\n filters.push(inArray(secretValues.key, params.keys));\n }\n const deleted = await executor\n .delete(secretValues)\n .where(and(...filters))\n .returning({id: secretValues.id});\n return deleted.length;\n}\n\nfunction batchProjectId(rows: SecretValueWrite[]): string | null {\n const projectId = normalizedProjectId({projectId: rows[0]?.projectId});\n const mixedScope = rows.some(\n (row) => normalizedProjectId({projectId: row.projectId}) !== projectId,\n );\n if (mixedScope) throw new SecretBatchScopeMismatchError();\n return projectId;\n}\n\nfunction listByNamespaceSql(params: StoreScope & {workspaceId: string; namespace: string}) {\n const projectId = normalizedProjectId(params);\n if (!projectId) {\n return sql`workspace_id = ${params.workspaceId} AND namespace = ${params.namespace} AND project_id IS NULL`;\n }\n return sql`workspace_id = ${params.workspaceId} AND namespace = ${params.namespace} AND (project_id = ${projectId} OR project_id IS NULL)`;\n}\n\ninterface SecretValueRow extends Record<string, unknown> {\n id: string;\n workspace_id: string;\n project_id: string | null;\n namespace: string;\n key: string;\n ciphertext: string;\n fingerprint: string | null;\n created_at: Date;\n updated_at: Date;\n last_edited_by: string | null;\n}\n\nfunction rowToSecretValue(row: SecretValueRow): SecretValue {\n return {\n id: row.id,\n workspaceId: row.workspace_id,\n projectId: row.project_id,\n namespace: row.namespace,\n key: row.key,\n ciphertext: row.ciphertext,\n fingerprint: row.fingerprint,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n lastEditedBy: row.last_edited_by,\n };\n}\n"],"names":["and","eq","inArray","isNull","sql","SecretBatchScopeMismatchError","db","secretValues","toSecretValue","lookupWithPrecedenceWhere","normalizedProjectId","scopeConflictTargetWhere","scopeExactWhere","getSecretValueRowWithPrecedence","params","tx","executor","rows","select","from","where","workspaceId","projectId","namespace","key","orderBy","limit","row","undefined","listSecretValueRowsByNamespace","execute","listByNamespaceSql","map","rowToSecretValue","upsertSecretValueRows","length","batchProjectId","insert","values","onConflictDoUpdate","target","targetWhere","set","ciphertext","fingerprint","lastEditedBy","updatedAt","countSecretValueRows","keys","count","Number","deleteSecretValueRows","filters","push","deleted","delete","returning","id","mixedScope","some","workspace_id","project_id","createdAt","created_at","updated_at","last_edited_by"],"mappings":"AAAA,SAAQA,GAAG,EAAEC,EAAE,EAAEC,OAAO,EAAEC,MAAM,EAAEC,GAAG,QAAO,cAAc;AAC1D,SAAQC,6BAA6B,QAAO,kBAAkB;AAC9D,SAAQC,EAAE,QAAgB,UAAU;AACpC,SAA0BC,YAAY,EAAEC,aAAa,QAAO,qBAAqB;AACjF,SACEC,yBAAyB,EACzBC,mBAAmB,EAEnBC,wBAAwB,EACxBC,eAAe,QACV,aAAa;AAYpB,OAAO,eAAeC,gCACpBC,MAA0E,EAC1EC,EAAO;IAEP,MAAMC,WAAWD,MAAMT;IACvB,MAAMW,OAAO,MAAMD,SAChBE,MAAM,GACNC,IAAI,CAACZ,cACLa,KAAK,CACJX,0BACE;QACEY,aAAad,aAAac,WAAW;QACrCC,WAAWf,aAAae,SAAS;QACjCC,WAAWhB,aAAagB,SAAS;QACjCC,KAAKjB,aAAaiB,GAAG;IACvB,GACAV,SAGHW,OAAO,CAACrB,GAAG,CAAC,EAAEG,aAAae,SAAS,CAAC,WAAW,CAAC,EACjDI,KAAK,CAAC;IACT,MAAMC,MAAMV,IAAI,CAAC,EAAE;IACnB,OAAOU,MAAMnB,cAAcmB,OAAOC;AACpC;AAEA,OAAO,eAAeC,+BACpBf,MAA6D,EAC7DC,EAAO;IAEP,MAAMC,WAAWD,MAAMT;IACvB,MAAMW,OAAO,MAAMD,SAASc,OAAO,CAAiB1B,GAAG,CAAC;;;;;UAKhD,EAAE2B,mBAAmBjB,QAAQ;;EAErC,CAAC;IACD,OAAOG,KAAKA,IAAI,CAACe,GAAG,CAACC;AACvB;AAEA,OAAO,eAAeC,sBAAsBjB,IAAwB,EAAEF,EAAM;IAC1E,IAAIE,KAAKkB,MAAM,KAAK,GAAG;IACvB,MAAMb,YAAYc,eAAenB;IACjC,MAAMF,GACHsB,MAAM,CAAC9B,cACP+B,MAAM,CAACrB,MACPsB,kBAAkB,CAAC;QAClBC,QAAQlB,YACJ;YACEf,aAAac,WAAW;YACxBd,aAAae,SAAS;YACtBf,aAAagB,SAAS;YACtBhB,aAAaiB,GAAG;SACjB,GACD;YAACjB,aAAac,WAAW;YAAEd,aAAagB,SAAS;YAAEhB,aAAaiB,GAAG;SAAC;QACxEiB,aAAa9B,yBAAyB;YAACW;QAAS;QAChDoB,KAAK;YACHC,YAAYvC,GAAG,CAAC,mBAAmB,CAAC;YACpCwC,aAAaxC,GAAG,CAAC,oBAAoB,CAAC;YACtCyC,cAAczC,GAAG,CAAC,uBAAuB,CAAC;YAC1C0C,WAAW1C,GAAG,CAAC,KAAK,CAAC;QACvB;IACF;AACJ;AAEA,OAAO,eAAe2C,qBACpBjC,MAA6E,EAC7EC,EAAM;IAEN,IAAID,OAAOkC,IAAI,CAACb,MAAM,KAAK,GAAG,OAAO;IAErC,MAAMlB,OAAO,MAAMF,GAChBG,MAAM,CAAC;QAAC+B,OAAO7C,GAAoB,CAAC,QAAQ,CAAC;IAAA,GAC7Ce,IAAI,CAACZ,cACLa,KAAK,CACJpB,IACEC,GAAGM,aAAac,WAAW,EAAEP,OAAOO,WAAW,GAC/CpB,GAAGM,aAAagB,SAAS,EAAET,OAAOS,SAAS,GAC3CX,gBACE;QACES,aAAad,aAAac,WAAW;QACrCC,WAAWf,aAAae,SAAS;QACjCC,WAAWhB,aAAagB,SAAS;QACjCC,KAAKjB,aAAaiB,GAAG;IACvB,GACAV,WACGX,OAAOI,aAAae,SAAS,GAClCpB,QAAQK,aAAaiB,GAAG,EAAEV,OAAOkC,IAAI;IAI3C,OAAOE,OAAOjC,IAAI,CAAC,EAAE,EAAEgC,SAAS;AAClC;AAEA,OAAO,eAAeE,sBACpBrC,MAA0F,EAC1FC,EAAO;IAEP,IAAID,OAAOkC,IAAI,IAAIlC,OAAOkC,IAAI,CAACb,MAAM,KAAK,GAAG,OAAO;IAEpD,MAAMnB,WAAWD,MAAMT;IACvB,MAAM8C,UAAU;QACdnD,GAAGM,aAAac,WAAW,EAAEP,OAAOO,WAAW;QAC/CpB,GAAGM,aAAagB,SAAS,EAAET,OAAOS,SAAS;QAC3CX,gBACE;YACES,aAAad,aAAac,WAAW;YACrCC,WAAWf,aAAae,SAAS;YACjCC,WAAWhB,aAAagB,SAAS;YACjCC,KAAKjB,aAAaiB,GAAG;QACvB,GACAV,WACGX,OAAOI,aAAae,SAAS;KACnC;IACD,IAAIR,OAAOkC,IAAI,IAAIlC,OAAOkC,IAAI,CAACb,MAAM,GAAG,GAAG;QACzCiB,QAAQC,IAAI,CAACnD,QAAQK,aAAaiB,GAAG,EAAEV,OAAOkC,IAAI;IACpD;IACA,MAAMM,UAAU,MAAMtC,SACnBuC,MAAM,CAAChD,cACPa,KAAK,CAACpB,OAAOoD,UACbI,SAAS,CAAC;QAACC,IAAIlD,aAAakD,EAAE;IAAA;IACjC,OAAOH,QAAQnB,MAAM;AACvB;AAEA,SAASC,eAAenB,IAAwB;IAC9C,MAAMK,YAAYZ,oBAAoB;QAACY,WAAWL,IAAI,CAAC,EAAE,EAAEK;IAAS;IACpE,MAAMoC,aAAazC,KAAK0C,IAAI,CAC1B,CAAChC,MAAQjB,oBAAoB;YAACY,WAAWK,IAAIL,SAAS;QAAA,OAAOA;IAE/D,IAAIoC,YAAY,MAAM,IAAIrD;IAC1B,OAAOiB;AACT;AAEA,SAASS,mBAAmBjB,MAA6D;IACvF,MAAMQ,YAAYZ,oBAAoBI;IACtC,IAAI,CAACQ,WAAW;QACd,OAAOlB,GAAG,CAAC,eAAe,EAAEU,OAAOO,WAAW,CAAC,iBAAiB,EAAEP,OAAOS,SAAS,CAAC,uBAAuB,CAAC;IAC7G;IACA,OAAOnB,GAAG,CAAC,eAAe,EAAEU,OAAOO,WAAW,CAAC,iBAAiB,EAAEP,OAAOS,SAAS,CAAC,mBAAmB,EAAED,UAAU,uBAAuB,CAAC;AAC5I;AAeA,SAASW,iBAAiBN,GAAmB;IAC3C,OAAO;QACL8B,IAAI9B,IAAI8B,EAAE;QACVpC,aAAaM,IAAIiC,YAAY;QAC7BtC,WAAWK,IAAIkC,UAAU;QACzBtC,WAAWI,IAAIJ,SAAS;QACxBC,KAAKG,IAAIH,GAAG;QACZmB,YAAYhB,IAAIgB,UAAU;QAC1BC,aAAajB,IAAIiB,WAAW;QAC5BkB,WAAWnC,IAAIoC,UAAU;QACzBjB,WAAWnB,IAAIqC,UAAU;QACzBnB,cAAclB,IAAIsC,cAAc;IAClC;AACF"}
@@ -0,0 +1,32 @@
1
+ import { type Tx } from './db.js';
2
+ import { type SecretVariable } from './schema/variables.js';
3
+ import { type StoreScope } from './scope.js';
4
+ export interface SecretVariableWrite {
5
+ workspaceId: string;
6
+ projectId: string | null;
7
+ namespace: string;
8
+ key: string;
9
+ value: string;
10
+ lastEditedBy?: string | null | undefined;
11
+ }
12
+ export declare function getSecretVariableRowWithPrecedence(params: StoreScope & {
13
+ workspaceId: string;
14
+ namespace: string;
15
+ key: string;
16
+ }, tx?: Tx): Promise<SecretVariable | undefined>;
17
+ export declare function listSecretVariableRowsByNamespace(params: StoreScope & {
18
+ workspaceId: string;
19
+ namespace: string;
20
+ }, tx?: Tx): Promise<SecretVariable[]>;
21
+ export declare function upsertSecretVariableRows(rows: SecretVariableWrite[], tx: Tx): Promise<void>;
22
+ export declare function countSecretVariableRows(params: StoreScope & {
23
+ workspaceId: string;
24
+ namespace: string;
25
+ keys: string[];
26
+ }, tx: Tx): Promise<number>;
27
+ export declare function deleteSecretVariableRows(params: StoreScope & {
28
+ workspaceId: string;
29
+ namespace: string;
30
+ keys?: string[] | undefined;
31
+ }, tx?: Tx): Promise<number>;
32
+ //# sourceMappingURL=variables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../src/db/variables.ts"],"names":[],"mappings":"AAEA,OAAO,EAAK,KAAK,EAAE,EAAC,MAAM,SAAS,CAAC;AACpC,OAAO,EAAC,KAAK,cAAc,EAAoC,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAGL,KAAK,UAAU,EAGhB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC1C;AAED,wBAAsB,kCAAkC,CACtD,MAAM,EAAE,UAAU,GAAG;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,EAC1E,EAAE,CAAC,EAAE,EAAE,GACN,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAoBrC;AAED,wBAAsB,iCAAiC,CACrD,MAAM,EAAE,UAAU,GAAG;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,EAC7D,EAAE,CAAC,EAAE,EAAE,GACN,OAAO,CAAC,cAAc,EAAE,CAAC,CAW3B;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBjG;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,UAAU,GAAG;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAC,EAC7E,EAAE,EAAE,EAAE,GACL,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,UAAU,GAAG;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;CAAC,EAC1F,EAAE,CAAC,EAAE,EAAE,GACN,OAAO,CAAC,MAAM,CAAC,CAyBjB"}
@@ -0,0 +1,117 @@
1
+ import { and, eq, inArray, isNull, sql } from 'drizzle-orm';
2
+ import { SecretBatchScopeMismatchError } from '#core/errors.js';
3
+ import { db } from './db.js';
4
+ import { secretVariables, toSecretVariable } from './schema/variables.js';
5
+ import { lookupWithPrecedenceWhere, normalizedProjectId, scopeConflictTargetWhere, scopeExactWhere } from './scope.js';
6
+ export async function getSecretVariableRowWithPrecedence(params, tx) {
7
+ const executor = tx ?? db();
8
+ const rows = await executor.select().from(secretVariables).where(lookupWithPrecedenceWhere({
9
+ workspaceId: secretVariables.workspaceId,
10
+ projectId: secretVariables.projectId,
11
+ namespace: secretVariables.namespace,
12
+ key: secretVariables.key
13
+ }, params)).orderBy(sql`${secretVariables.projectId} NULLS LAST`).limit(1);
14
+ const row = rows[0];
15
+ return row ? toSecretVariable(row) : undefined;
16
+ }
17
+ export async function listSecretVariableRowsByNamespace(params, tx) {
18
+ const executor = tx ?? db();
19
+ const rows = await executor.execute(sql`
20
+ SELECT DISTINCT ON (key)
21
+ id, workspace_id, project_id, namespace, key, value,
22
+ created_at, updated_at, last_edited_by
23
+ FROM secrets_variables
24
+ WHERE ${listByNamespaceSql(params)}
25
+ ORDER BY key, project_id NULLS LAST, id
26
+ `);
27
+ return rows.rows.map(rowToSecretVariable);
28
+ }
29
+ export async function upsertSecretVariableRows(rows, tx) {
30
+ if (rows.length === 0) return;
31
+ const projectId = batchProjectId(rows);
32
+ await tx.insert(secretVariables).values(rows).onConflictDoUpdate({
33
+ target: projectId ? [
34
+ secretVariables.workspaceId,
35
+ secretVariables.projectId,
36
+ secretVariables.namespace,
37
+ secretVariables.key
38
+ ] : [
39
+ secretVariables.workspaceId,
40
+ secretVariables.namespace,
41
+ secretVariables.key
42
+ ],
43
+ targetWhere: scopeConflictTargetWhere({
44
+ projectId
45
+ }),
46
+ set: {
47
+ value: sql`excluded.value`,
48
+ lastEditedBy: sql`excluded.last_edited_by`,
49
+ updatedAt: sql`NOW()`
50
+ }
51
+ });
52
+ }
53
+ export async function countSecretVariableRows(params, tx) {
54
+ if (params.keys.length === 0) return 0;
55
+ const rows = await tx.select({
56
+ count: sql`COUNT(*)`
57
+ }).from(secretVariables).where(and(eq(secretVariables.workspaceId, params.workspaceId), eq(secretVariables.namespace, params.namespace), scopeExactWhere({
58
+ workspaceId: secretVariables.workspaceId,
59
+ projectId: secretVariables.projectId,
60
+ namespace: secretVariables.namespace,
61
+ key: secretVariables.key
62
+ }, params) ?? isNull(secretVariables.projectId), inArray(secretVariables.key, params.keys)));
63
+ return Number(rows[0]?.count ?? 0);
64
+ }
65
+ export async function deleteSecretVariableRows(params, tx) {
66
+ if (params.keys && params.keys.length === 0) return 0;
67
+ const executor = tx ?? db();
68
+ const filters = [
69
+ eq(secretVariables.workspaceId, params.workspaceId),
70
+ eq(secretVariables.namespace, params.namespace),
71
+ scopeExactWhere({
72
+ workspaceId: secretVariables.workspaceId,
73
+ projectId: secretVariables.projectId,
74
+ namespace: secretVariables.namespace,
75
+ key: secretVariables.key
76
+ }, params) ?? isNull(secretVariables.projectId)
77
+ ];
78
+ if (params.keys && params.keys.length > 0) {
79
+ filters.push(inArray(secretVariables.key, params.keys));
80
+ }
81
+ const deleted = await executor.delete(secretVariables).where(and(...filters)).returning({
82
+ id: secretVariables.id
83
+ });
84
+ return deleted.length;
85
+ }
86
+ function batchProjectId(rows) {
87
+ const projectId = normalizedProjectId({
88
+ projectId: rows[0]?.projectId
89
+ });
90
+ const mixedScope = rows.some((row)=>normalizedProjectId({
91
+ projectId: row.projectId
92
+ }) !== projectId);
93
+ if (mixedScope) throw new SecretBatchScopeMismatchError();
94
+ return projectId;
95
+ }
96
+ function listByNamespaceSql(params) {
97
+ const projectId = normalizedProjectId(params);
98
+ if (!projectId) {
99
+ return sql`workspace_id = ${params.workspaceId} AND namespace = ${params.namespace} AND project_id IS NULL`;
100
+ }
101
+ return sql`workspace_id = ${params.workspaceId} AND namespace = ${params.namespace} AND (project_id = ${projectId} OR project_id IS NULL)`;
102
+ }
103
+ function rowToSecretVariable(row) {
104
+ return {
105
+ id: row.id,
106
+ workspaceId: row.workspace_id,
107
+ projectId: row.project_id,
108
+ namespace: row.namespace,
109
+ key: row.key,
110
+ value: row.value,
111
+ createdAt: row.created_at,
112
+ updatedAt: row.updated_at,
113
+ lastEditedBy: row.last_edited_by
114
+ };
115
+ }
116
+
117
+ //# sourceMappingURL=variables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/db/variables.ts"],"sourcesContent":["import {and, eq, inArray, isNull, sql} from 'drizzle-orm';\nimport {SecretBatchScopeMismatchError} from '#core/errors.js';\nimport {db, type Tx} from './db.js';\nimport {type SecretVariable, secretVariables, toSecretVariable} from './schema/variables.js';\nimport {\n lookupWithPrecedenceWhere,\n normalizedProjectId,\n type StoreScope,\n scopeConflictTargetWhere,\n scopeExactWhere,\n} from './scope.js';\n\nexport interface SecretVariableWrite {\n workspaceId: string;\n projectId: string | null;\n namespace: string;\n key: string;\n value: string;\n lastEditedBy?: string | null | undefined;\n}\n\nexport async function getSecretVariableRowWithPrecedence(\n params: StoreScope & {workspaceId: string; namespace: string; key: string},\n tx?: Tx,\n): Promise<SecretVariable | undefined> {\n const executor = tx ?? db();\n const rows = await executor\n .select()\n .from(secretVariables)\n .where(\n lookupWithPrecedenceWhere(\n {\n workspaceId: secretVariables.workspaceId,\n projectId: secretVariables.projectId,\n namespace: secretVariables.namespace,\n key: secretVariables.key,\n },\n params,\n ),\n )\n .orderBy(sql`${secretVariables.projectId} NULLS LAST`)\n .limit(1);\n const row = rows[0];\n return row ? toSecretVariable(row) : undefined;\n}\n\nexport async function listSecretVariableRowsByNamespace(\n params: StoreScope & {workspaceId: string; namespace: string},\n tx?: Tx,\n): Promise<SecretVariable[]> {\n const executor = tx ?? db();\n const rows = await executor.execute<SecretVariableRow>(sql`\n SELECT DISTINCT ON (key)\n id, workspace_id, project_id, namespace, key, value,\n created_at, updated_at, last_edited_by\n FROM secrets_variables\n WHERE ${listByNamespaceSql(params)}\n ORDER BY key, project_id NULLS LAST, id\n `);\n return rows.rows.map(rowToSecretVariable);\n}\n\nexport async function upsertSecretVariableRows(rows: SecretVariableWrite[], tx: Tx): Promise<void> {\n if (rows.length === 0) return;\n const projectId = batchProjectId(rows);\n await tx\n .insert(secretVariables)\n .values(rows)\n .onConflictDoUpdate({\n target: projectId\n ? [\n secretVariables.workspaceId,\n secretVariables.projectId,\n secretVariables.namespace,\n secretVariables.key,\n ]\n : [secretVariables.workspaceId, secretVariables.namespace, secretVariables.key],\n targetWhere: scopeConflictTargetWhere({projectId}),\n set: {\n value: sql`excluded.value`,\n lastEditedBy: sql`excluded.last_edited_by`,\n updatedAt: sql`NOW()`,\n },\n });\n}\n\nexport async function countSecretVariableRows(\n params: StoreScope & {workspaceId: string; namespace: string; keys: string[]},\n tx: Tx,\n): Promise<number> {\n if (params.keys.length === 0) return 0;\n\n const rows = await tx\n .select({count: sql<string | number>`COUNT(*)`})\n .from(secretVariables)\n .where(\n and(\n eq(secretVariables.workspaceId, params.workspaceId),\n eq(secretVariables.namespace, params.namespace),\n scopeExactWhere(\n {\n workspaceId: secretVariables.workspaceId,\n projectId: secretVariables.projectId,\n namespace: secretVariables.namespace,\n key: secretVariables.key,\n },\n params,\n ) ?? isNull(secretVariables.projectId),\n inArray(secretVariables.key, params.keys),\n ),\n );\n\n return Number(rows[0]?.count ?? 0);\n}\n\nexport async function deleteSecretVariableRows(\n params: StoreScope & {workspaceId: string; namespace: string; keys?: string[] | undefined},\n tx?: Tx,\n): Promise<number> {\n if (params.keys && params.keys.length === 0) return 0;\n\n const executor = tx ?? db();\n const filters = [\n eq(secretVariables.workspaceId, params.workspaceId),\n eq(secretVariables.namespace, params.namespace),\n scopeExactWhere(\n {\n workspaceId: secretVariables.workspaceId,\n projectId: secretVariables.projectId,\n namespace: secretVariables.namespace,\n key: secretVariables.key,\n },\n params,\n ) ?? isNull(secretVariables.projectId),\n ];\n if (params.keys && params.keys.length > 0) {\n filters.push(inArray(secretVariables.key, params.keys));\n }\n const deleted = await executor\n .delete(secretVariables)\n .where(and(...filters))\n .returning({id: secretVariables.id});\n return deleted.length;\n}\n\nfunction batchProjectId(rows: SecretVariableWrite[]): string | null {\n const projectId = normalizedProjectId({projectId: rows[0]?.projectId});\n const mixedScope = rows.some(\n (row) => normalizedProjectId({projectId: row.projectId}) !== projectId,\n );\n if (mixedScope) throw new SecretBatchScopeMismatchError();\n return projectId;\n}\n\nfunction listByNamespaceSql(params: StoreScope & {workspaceId: string; namespace: string}) {\n const projectId = normalizedProjectId(params);\n if (!projectId) {\n return sql`workspace_id = ${params.workspaceId} AND namespace = ${params.namespace} AND project_id IS NULL`;\n }\n return sql`workspace_id = ${params.workspaceId} AND namespace = ${params.namespace} AND (project_id = ${projectId} OR project_id IS NULL)`;\n}\n\ninterface SecretVariableRow extends Record<string, unknown> {\n id: string;\n workspace_id: string;\n project_id: string | null;\n namespace: string;\n key: string;\n value: string;\n created_at: Date;\n updated_at: Date;\n last_edited_by: string | null;\n}\n\nfunction rowToSecretVariable(row: SecretVariableRow): SecretVariable {\n return {\n id: row.id,\n workspaceId: row.workspace_id,\n projectId: row.project_id,\n namespace: row.namespace,\n key: row.key,\n value: row.value,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n lastEditedBy: row.last_edited_by,\n };\n}\n"],"names":["and","eq","inArray","isNull","sql","SecretBatchScopeMismatchError","db","secretVariables","toSecretVariable","lookupWithPrecedenceWhere","normalizedProjectId","scopeConflictTargetWhere","scopeExactWhere","getSecretVariableRowWithPrecedence","params","tx","executor","rows","select","from","where","workspaceId","projectId","namespace","key","orderBy","limit","row","undefined","listSecretVariableRowsByNamespace","execute","listByNamespaceSql","map","rowToSecretVariable","upsertSecretVariableRows","length","batchProjectId","insert","values","onConflictDoUpdate","target","targetWhere","set","value","lastEditedBy","updatedAt","countSecretVariableRows","keys","count","Number","deleteSecretVariableRows","filters","push","deleted","delete","returning","id","mixedScope","some","workspace_id","project_id","createdAt","created_at","updated_at","last_edited_by"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ShipfoxModule } from '@shipfox/node-module';
2
+ export { BUILTIN_LOCAL_STORE, DekUnwrapError, DekWrapError, deleteManagedSecret, deleteManagedVariable, deleteSecrets, deleteVariables, getManagedVariable, getSecret, getSecretsByNamespace, getVariable, getVariablesByNamespace, KekConfigurationError, KekVersionStrandedError, listManagedSecrets, listManagedVariables, NamespaceValidationError, resolveSecretStore, rotateWorkspaceDataKeys, SecretBatchScopeMismatchError, SecretDecryptionError, SecretKeyValidationError, SecretNotFoundError, type SecretStoreProvider, SecretValueTooLargeError, setManagedSecrets, setManagedVariables, setSecrets, setVariables, UnknownSecretStoreError, VariableNotFoundError, WorkspaceSecretCapExceededError, } from '#core/index.js';
3
+ export declare const secretsModule: ShipfoxModule;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AAMxD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,SAAS,EACT,qBAAqB,EACrB,WAAW,EACX,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,EACvB,6BAA6B,EAC7B,qBAAqB,EACrB,wBAAwB,EACxB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,EACV,YAAY,EACZ,uBAAuB,EACvB,qBAAqB,EACrB,+BAA+B,GAChC,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,aAAa,EAAE,aAO3B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ import { secretsEventSchemas } from '@shipfox/api-secrets-dto';
2
+ import { db, migrationsPath, secretsOutbox } from '#db/index.js';
3
+ import { registerSecretsServiceMetrics } from '#metrics/index.js';
4
+ import { secretsE2eRoutes } from '#presentation/e2eRoutes/index.js';
5
+ import { secretsRoutes } from '#presentation/routes/index.js';
6
+ export { BUILTIN_LOCAL_STORE, DekUnwrapError, DekWrapError, deleteManagedSecret, deleteManagedVariable, deleteSecrets, deleteVariables, getManagedVariable, getSecret, getSecretsByNamespace, getVariable, getVariablesByNamespace, KekConfigurationError, KekVersionStrandedError, listManagedSecrets, listManagedVariables, NamespaceValidationError, resolveSecretStore, rotateWorkspaceDataKeys, SecretBatchScopeMismatchError, SecretDecryptionError, SecretKeyValidationError, SecretNotFoundError, SecretValueTooLargeError, setManagedSecrets, setManagedVariables, setSecrets, setVariables, UnknownSecretStoreError, VariableNotFoundError, WorkspaceSecretCapExceededError } from '#core/index.js';
7
+ export const secretsModule = {
8
+ name: 'secrets',
9
+ database: {
10
+ db,
11
+ migrationsPath
12
+ },
13
+ routes: secretsRoutes,
14
+ e2eRoutes: [
15
+ secretsE2eRoutes
16
+ ],
17
+ metrics: registerSecretsServiceMetrics,
18
+ publishers: [
19
+ {
20
+ name: 'secrets',
21
+ table: secretsOutbox,
22
+ db,
23
+ eventSchemas: secretsEventSchemas
24
+ }
25
+ ]
26
+ };
27
+
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {secretsEventSchemas} from '@shipfox/api-secrets-dto';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {db, migrationsPath, secretsOutbox} from '#db/index.js';\nimport {registerSecretsServiceMetrics} from '#metrics/index.js';\nimport {secretsE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {secretsRoutes} from '#presentation/routes/index.js';\n\nexport {\n BUILTIN_LOCAL_STORE,\n DekUnwrapError,\n DekWrapError,\n deleteManagedSecret,\n deleteManagedVariable,\n deleteSecrets,\n deleteVariables,\n getManagedVariable,\n getSecret,\n getSecretsByNamespace,\n getVariable,\n getVariablesByNamespace,\n KekConfigurationError,\n KekVersionStrandedError,\n listManagedSecrets,\n listManagedVariables,\n NamespaceValidationError,\n resolveSecretStore,\n rotateWorkspaceDataKeys,\n SecretBatchScopeMismatchError,\n SecretDecryptionError,\n SecretKeyValidationError,\n SecretNotFoundError,\n type SecretStoreProvider,\n SecretValueTooLargeError,\n setManagedSecrets,\n setManagedVariables,\n setSecrets,\n setVariables,\n UnknownSecretStoreError,\n VariableNotFoundError,\n WorkspaceSecretCapExceededError,\n} from '#core/index.js';\n\nexport const secretsModule: ShipfoxModule = {\n name: 'secrets',\n database: {db, migrationsPath},\n routes: secretsRoutes,\n e2eRoutes: [secretsE2eRoutes],\n metrics: registerSecretsServiceMetrics,\n publishers: [{name: 'secrets', table: secretsOutbox, db, eventSchemas: secretsEventSchemas}],\n};\n"],"names":["secretsEventSchemas","db","migrationsPath","secretsOutbox","registerSecretsServiceMetrics","secretsE2eRoutes","secretsRoutes","BUILTIN_LOCAL_STORE","DekUnwrapError","DekWrapError","deleteManagedSecret","deleteManagedVariable","deleteSecrets","deleteVariables","getManagedVariable","getSecret","getSecretsByNamespace","getVariable","getVariablesByNamespace","KekConfigurationError","KekVersionStrandedError","listManagedSecrets","listManagedVariables","NamespaceValidationError","resolveSecretStore","rotateWorkspaceDataKeys","SecretBatchScopeMismatchError","SecretDecryptionError","SecretKeyValidationError","SecretNotFoundError","SecretValueTooLargeError","setManagedSecrets","setManagedVariables","setSecrets","setVariables","UnknownSecretStoreError","VariableNotFoundError","WorkspaceSecretCapExceededError","secretsModule","name","database","routes","e2eRoutes","metrics","publishers","table","eventSchemas"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,2BAA2B;AAE7D,SAAQC,EAAE,EAAEC,cAAc,EAAEC,aAAa,QAAO,eAAe;AAC/D,SAAQC,6BAA6B,QAAO,oBAAoB;AAChE,SAAQC,gBAAgB,QAAO,mCAAmC;AAClE,SAAQC,aAAa,QAAO,gCAAgC;AAE5D,SACEC,mBAAmB,EACnBC,cAAc,EACdC,YAAY,EACZC,mBAAmB,EACnBC,qBAAqB,EACrBC,aAAa,EACbC,eAAe,EACfC,kBAAkB,EAClBC,SAAS,EACTC,qBAAqB,EACrBC,WAAW,EACXC,uBAAuB,EACvBC,qBAAqB,EACrBC,uBAAuB,EACvBC,kBAAkB,EAClBC,oBAAoB,EACpBC,wBAAwB,EACxBC,kBAAkB,EAClBC,uBAAuB,EACvBC,6BAA6B,EAC7BC,qBAAqB,EACrBC,wBAAwB,EACxBC,mBAAmB,EAEnBC,wBAAwB,EACxBC,iBAAiB,EACjBC,mBAAmB,EACnBC,UAAU,EACVC,YAAY,EACZC,uBAAuB,EACvBC,qBAAqB,EACrBC,+BAA+B,QAC1B,iBAAiB;AAExB,OAAO,MAAMC,gBAA+B;IAC1CC,MAAM;IACNC,UAAU;QAACvC;QAAIC;IAAc;IAC7BuC,QAAQnC;IACRoC,WAAW;QAACrC;KAAiB;IAC7BsC,SAASvC;IACTwC,YAAY;QAAC;YAACL,MAAM;YAAWM,OAAO1C;YAAeF;YAAI6C,cAAc9C;QAAmB;KAAE;AAC9F,EAAE"}
@@ -0,0 +1,3 @@
1
+ export { classifyDekAccessError, classifyKekRotationError, classifySecretsOperationError, operationScope, recordSecretsDekAccess, recordSecretsEntriesMutated, recordSecretsKekRotation, recordSecretsOperation, type SecretsDekAccessOutcome, type SecretsKekRotationOutcome, type SecretsMetricOperation, type SecretsMetricResource, type SecretsMetricScope, type SecretsMetricSurface, type SecretsMutationEffect, type SecretsOperationOutcome, } from './instance.js';
2
+ export { registerSecretsServiceMetrics } from './service.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,6BAA6B,EAC7B,cAAc,EACd,sBAAsB,EACtB,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,GAC7B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,6BAA6B,EAAC,MAAM,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { classifyDekAccessError, classifyKekRotationError, classifySecretsOperationError, operationScope, recordSecretsDekAccess, recordSecretsEntriesMutated, recordSecretsKekRotation, recordSecretsOperation } from './instance.js';
2
+ export { registerSecretsServiceMetrics } from './service.js';
3
+
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/metrics/index.ts"],"sourcesContent":["export {\n classifyDekAccessError,\n classifyKekRotationError,\n classifySecretsOperationError,\n operationScope,\n recordSecretsDekAccess,\n recordSecretsEntriesMutated,\n recordSecretsKekRotation,\n recordSecretsOperation,\n type SecretsDekAccessOutcome,\n type SecretsKekRotationOutcome,\n type SecretsMetricOperation,\n type SecretsMetricResource,\n type SecretsMetricScope,\n type SecretsMetricSurface,\n type SecretsMutationEffect,\n type SecretsOperationOutcome,\n} from './instance.js';\nexport {registerSecretsServiceMetrics} from './service.js';\n"],"names":["classifyDekAccessError","classifyKekRotationError","classifySecretsOperationError","operationScope","recordSecretsDekAccess","recordSecretsEntriesMutated","recordSecretsKekRotation","recordSecretsOperation","registerSecretsServiceMetrics"],"mappings":"AAAA,SACEA,sBAAsB,EACtBC,wBAAwB,EACxBC,6BAA6B,EAC7BC,cAAc,EACdC,sBAAsB,EACtBC,2BAA2B,EAC3BC,wBAAwB,EACxBC,sBAAsB,QASjB,gBAAgB;AACvB,SAAQC,6BAA6B,QAAO,eAAe"}
@@ -0,0 +1,39 @@
1
+ export type SecretsMetricResource = 'secret' | 'variable';
2
+ export type SecretsMetricOperation = 'get' | 'get_namespace' | 'set' | 'delete' | 'list';
3
+ export type SecretsMetricSurface = 'internal' | 'management';
4
+ export type SecretsMetricScope = 'workspace' | 'project';
5
+ export type SecretsOperationOutcome = 'success' | 'not_found' | 'validation_failed' | 'cap_exceeded' | 'value_too_large' | 'decryption_failed' | 'crypto_failed' | 'failure';
6
+ export type SecretsMutationEffect = 'created' | 'updated' | 'deleted';
7
+ export type SecretsDekAccessOutcome = 'cache_hit' | 'cache_expired' | 'db_unwrapped' | 'generated' | 'unwrap_failed' | 'wrap_failed' | 'failure';
8
+ export type SecretsKekRotationOutcome = 'rotated' | 'skipped_current' | 'skipped_race' | 'none' | 'stranded' | 'failure';
9
+ export declare function operationScope(params: {
10
+ projectId?: string | null | undefined;
11
+ }): SecretsMetricScope;
12
+ export declare function classifySecretsOperationError(error: unknown): SecretsOperationOutcome;
13
+ export declare function recordSecretsOperation(params: {
14
+ resource: SecretsMetricResource;
15
+ operation: SecretsMetricOperation;
16
+ surface: SecretsMetricSurface;
17
+ scope: SecretsMetricScope;
18
+ outcome: SecretsOperationOutcome;
19
+ durationMs: number;
20
+ }): void;
21
+ export declare function recordSecretsEntriesMutated(params: {
22
+ resource: SecretsMetricResource;
23
+ operation: 'set' | 'delete';
24
+ effect: SecretsMutationEffect;
25
+ surface: SecretsMetricSurface;
26
+ count: number;
27
+ }): void;
28
+ export declare function recordSecretsDekAccess(params: {
29
+ outcome: SecretsDekAccessOutcome;
30
+ durationMs: number;
31
+ }): void;
32
+ export declare function classifyDekAccessError(error: unknown): SecretsDekAccessOutcome;
33
+ export declare function recordSecretsKekRotation(params: {
34
+ outcome: SecretsKekRotationOutcome;
35
+ count?: number | undefined;
36
+ durationMs?: number | undefined;
37
+ }): void;
38
+ export declare function classifyKekRotationError(error: unknown): SecretsKekRotationOutcome;
39
+ //# sourceMappingURL=instance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/metrics/instance.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC1D,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AACzF,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,YAAY,CAAC;AAC7D,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,CAAC;AACzD,MAAM,MAAM,uBAAuB,GAC/B,SAAS,GACT,WAAW,GACX,mBAAmB,GACnB,cAAc,GACd,iBAAiB,GACjB,mBAAmB,GACnB,eAAe,GACf,SAAS,CAAC;AACd,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AACtE,MAAM,MAAM,uBAAuB,GAC/B,WAAW,GACX,eAAe,GACf,cAAc,GACd,WAAW,GACX,eAAe,GACf,aAAa,GACb,SAAS,CAAC;AACd,MAAM,MAAM,yBAAyB,GACjC,SAAS,GACT,iBAAiB,GACjB,cAAc,GACd,MAAM,GACN,UAAU,GACV,SAAS,CAAC;AAqEd,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC,GAAG,kBAAkB,CAErB;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CAkBrF;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,QAAQ,EAAE,qBAAqB,CAAC;IAChC,SAAS,EAAE,sBAAsB,CAAC;IAClC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,OAAO,EAAE,uBAAuB,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAYP;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,QAAQ,EAAE,qBAAqB,CAAC;IAChC,SAAS,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC5B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAWP;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,OAAO,EAAE,uBAAuB,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAKP;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CAI9E;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,OAAO,EAAE,yBAAyB,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC,GAAG,IAAI,CAUP;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CAIlF"}