1
+ import { readApplicationConfig } from "../../config/application" ;
2
+ import * as Table from 'cli-table3'
3
+ import { policyControllerCreate , policyControllerFindAll , policyControllerRemove , policyRuleControllerCreate , policyRuleControllerFindAll , policyRuleControllerRemove , policyRuleControllerUpdate } from "../../api/v1/database" ;
4
+ import { formatDate } from "../../util/format" ;
5
+ import * as path from "node:path" ;
6
+ import * as fs from "node:fs" ;
7
+ import { POLICIES_DIRECTORY_NAME } from "../../common/constant" ;
8
+ import { writeYamlFile , loadYamlFile } from "../../util/file" ;
9
+ import { CreatePolicyDto , CreatePolicyRuleDto , UpdatePolicyRuleDto } from "../../api/v1/data-contracts" ;
10
+ import { getEmoji } from "../../util/print" ;
11
+ import { getApplicationPath } from "../../util/sys" ;
12
+ import { confirm } from "../../common/prompts" ;
13
+
14
+ export async function list ( ) {
15
+ const appConfig = readApplicationConfig ( )
16
+ const policies = await policyControllerFindAll ( appConfig . appid )
17
+ const table = new Table ( {
18
+ head : [ 'name' , 'ruleCount' , 'createdAt' ] ,
19
+ } )
20
+ for ( let item of policies ) {
21
+ table . push ( [ item . name , item . rules ?. length , formatDate ( item . createdAt ) ] )
22
+ }
23
+ console . log ( table . toString ( ) ) ;
24
+ }
25
+
26
+ export async function pullOne ( policyName : string ) {
27
+ await pull ( policyName )
28
+ console . log ( `${ getEmoji ( '✅' ) } pull policy ${ policyName } success` )
29
+ }
30
+
31
+ export async function pullAll ( ) {
32
+ const appConfig = readApplicationConfig ( )
33
+ const policies = await policyControllerFindAll ( appConfig . appid )
34
+
35
+ for ( let item of policies ) {
36
+ await pull ( item . name )
37
+ }
38
+
39
+ console . log ( `${ getEmoji ( '✅' ) } pull all policies success` )
40
+ }
41
+
42
+
43
+
44
+ async function pull ( policyName : string ) {
45
+ const appConfig = readApplicationConfig ( )
46
+ const rules = await policyRuleControllerFindAll ( appConfig . appid , policyName )
47
+ const rulePath = path . join ( process . cwd ( ) , POLICIES_DIRECTORY_NAME , policyName + '.yaml' )
48
+ const ruleList : PolicyRule [ ] = [ ]
49
+ for ( let item of rules ) {
50
+ ruleList . push ( {
51
+ collectionName : item . collectionName ,
52
+ rules : {
53
+ read : item . value . read ,
54
+ count : item . value . count ,
55
+ update : item . value . update ,
56
+ remove : item . value . remove ,
57
+ add : item . value . add
58
+ }
59
+ } )
60
+ }
61
+ writeYamlFile ( rulePath , ruleList )
62
+ }
63
+
64
+
65
+
66
+ export async function pushOne ( policyName : string ) {
67
+ const appConfig = readApplicationConfig ( )
68
+ const policies = await policyControllerFindAll ( appConfig . appid )
69
+ let isCreate = true
70
+ for ( let item of policies ) {
71
+ if ( item . name === policyName ) {
72
+ isCreate = false
73
+ break
74
+ }
75
+ }
76
+ await push ( policyName , isCreate )
77
+ console . log ( `${ getEmoji ( '✅' ) } push policy ${ policyName } success` )
78
+ }
79
+
80
+ export async function pushAll ( options : { force : boolean } ) {
81
+ const appConfig = readApplicationConfig ( )
82
+
83
+ // get server policies
84
+ const serverPolicies = await policyControllerFindAll ( appConfig . appid )
85
+ const serverPoliciesMap = new Map < string , boolean > ( )
86
+ for ( let item of serverPolicies ) {
87
+ serverPoliciesMap . set ( item . name , true )
88
+ }
89
+
90
+ // get local policies
91
+ const localPolicies = getLocalPolicies ( )
92
+ const localPoliciesMap = new Map < string , boolean > ( )
93
+ for ( let item of localPolicies ) {
94
+ localPoliciesMap . set ( item , true )
95
+ }
96
+
97
+ // push local policies
98
+ for ( let item of localPolicies ) {
99
+ await push ( item , ! serverPoliciesMap . has ( item ) )
100
+ }
101
+
102
+ // delete server policies
103
+ for ( let item of serverPolicies ) {
104
+ if ( ! localPoliciesMap . has ( item . name ) ) {
105
+ if ( options . force ) {
106
+ await policyControllerRemove ( appConfig . appid , item . name )
107
+ } else {
108
+ const res = await confirm ( 'confirm remove policy ' + item . name + '?' )
109
+ if ( res . value ) {
110
+ await policyControllerRemove ( appConfig . appid , item . name )
111
+ } else {
112
+ console . log ( `${ getEmoji ( '🎃' ) } cancel remove policy ${ item . name } ` )
113
+ }
114
+ }
115
+ }
116
+ }
117
+ console . log ( `${ getEmoji ( '✅' ) } push all policies success` )
118
+ }
119
+
120
+ async function push ( policyName : string , isCreate : boolean ) {
121
+ const appConfig = readApplicationConfig ( )
122
+ if ( isCreate ) {
123
+ const createPolicyDto : CreatePolicyDto = {
124
+ name : policyName
125
+ }
126
+ await policyControllerCreate ( appConfig . appid , createPolicyDto )
127
+ }
128
+ const serverRules = await policyRuleControllerFindAll ( appConfig . appid , policyName )
129
+ const serverRulesMap = new Map < string , boolean > ( )
130
+ for ( let item of serverRules ) {
131
+ serverRulesMap . set ( item . collectionName , true )
132
+ }
133
+ const rulePath = path . join ( process . cwd ( ) , POLICIES_DIRECTORY_NAME , policyName + '.yaml' )
134
+ const localRules : PolicyRule [ ] = loadYamlFile ( rulePath )
135
+ const localRulesMap = new Map < string , boolean > ( )
136
+
137
+ // update or create rule
138
+ for ( let item of localRules ) {
139
+ if ( serverRulesMap . has ( item . collectionName ) ) { // rule exist, update
140
+ const updateRuleDto : UpdatePolicyRuleDto = {
141
+ value : JSON . stringify ( item . rules )
142
+ }
143
+ await policyRuleControllerUpdate ( appConfig . appid , policyName , item . collectionName , updateRuleDto )
144
+ } else { // rule not exist, create
145
+ const createRuleDto : CreatePolicyRuleDto = {
146
+ collectionName : item . collectionName ,
147
+ value : JSON . stringify ( item . rules )
148
+ }
149
+ await policyRuleControllerCreate ( appConfig . appid , policyName , createRuleDto )
150
+ }
151
+ localRulesMap . set ( item . collectionName , true )
152
+ }
153
+
154
+ // delete rule
155
+ for ( let item of serverRules ) {
156
+ if ( ! localRulesMap . has ( item . collectionName ) ) {
157
+ await policyRuleControllerRemove ( appConfig . appid , policyName , item . collectionName )
158
+ }
159
+ }
160
+ }
161
+
162
+
163
+ function getLocalPolicies ( ) : string [ ] {
164
+ const dir = path . join ( getApplicationPath ( ) , POLICIES_DIRECTORY_NAME )
165
+ const files = fs . readdirSync ( dir )
166
+ const policies : string [ ] = [ ]
167
+ for ( let item of files ) {
168
+ if ( item . endsWith ( '.yaml' ) ) {
169
+ policies . push ( item . replace ( '.yaml' , '' ) )
170
+ }
171
+ }
172
+ return policies
173
+ }
0 commit comments