backend-plus 1.15.2 → 1.16.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/for-client/my-tables.js +18 -0
- package/lib/backend-plus.d.ts +1 -0
- package/lib/backend-plus.js +6 -1
- package/lib/procedures-table.js +71 -14
- package/package.json +13 -12
- package/for-client/local-prueba.js +0 -15
package/for-client/my-tables.js
CHANGED
|
@@ -79,10 +79,14 @@ myOwn.i18n.messages.en=changing(myOwn.i18n.messages.en, {
|
|
|
79
79
|
notSimilarTo:'not similar to',
|
|
80
80
|
numberExportedRows:"Rows exported",
|
|
81
81
|
oldValue: "old value",
|
|
82
|
+
oneRowDeleted: "one row deleted.",
|
|
83
|
+
xRowsDeleted: "{$x} rows deleted.",
|
|
82
84
|
oneRowInserted: "one row inserted.",
|
|
83
85
|
xRowsInserted: "{$x} rows inserted.",
|
|
84
86
|
oneRowUpdated: "one row updated.",
|
|
85
87
|
xRowsUpdated: "{$x} rows updated.",
|
|
88
|
+
oneRowSkipped: "one skipped row",
|
|
89
|
+
xRowsSkipped: "{$x} skipped row",
|
|
86
90
|
optionsForThisTable: "options for this table",
|
|
87
91
|
orientationToggle: "toggle orientation (vertical vs horizontal)",
|
|
88
92
|
prepare: "prepare",
|
|
@@ -143,10 +147,14 @@ myOwn.i18n.messages.es=changing(myOwn.i18n.messages.es, {
|
|
|
143
147
|
notSimilarTo:'no contiene',
|
|
144
148
|
numberExportedRows:"Filas exportadas",
|
|
145
149
|
oldValue: "valor anterior",
|
|
150
|
+
oneRowDeleted: "un registro borrado",
|
|
151
|
+
xRowsDeleted: "{$x} registros borrados",
|
|
146
152
|
oneRowInserted: "un registro insertado.",
|
|
147
153
|
xRowsInserted: "{$x} registros insertados.",
|
|
148
154
|
oneRowUpdated: "un registro modificados.",
|
|
149
155
|
xRowsUpdated: "{$x} registros modificados.",
|
|
156
|
+
oneRowSkipped: "un registro salteado",
|
|
157
|
+
xRowsSkipped: "{$x} registros salteados",
|
|
150
158
|
optionsForThisTable: "opciones para esta tabla",
|
|
151
159
|
orientationToggle: "cambiar la orientación de la tabla (por fila o por columna)",
|
|
152
160
|
prepare: "preparar",
|
|
@@ -1336,6 +1344,16 @@ myOwn.TableGrid.prototype.prepareMenu = function prepareMenu(button){
|
|
|
1336
1344
|
}else if(result.uploaded.updated>1){
|
|
1337
1345
|
messages.push(my.messages.xRowsUpdated.replace('{$x}',result.uploaded.updated));
|
|
1338
1346
|
}
|
|
1347
|
+
if(result.uploaded.skipped==1){
|
|
1348
|
+
messages.push(my.messages.oneRowSkipped);
|
|
1349
|
+
}else if(result.uploaded.skipped>1){
|
|
1350
|
+
messages.push(my.messages.xRowsSkipped.replace('{$x}',result.uploaded.skipped));
|
|
1351
|
+
}
|
|
1352
|
+
if(result.uploaded.deleted==1){
|
|
1353
|
+
messages.push(my.messages.oneRowDeleted);
|
|
1354
|
+
}else if(result.uploaded.deleted>1){
|
|
1355
|
+
messages.push(my.messages.xRowsDeleted.replace('{$x}',result.uploaded.deleted));
|
|
1356
|
+
}
|
|
1339
1357
|
if(result.uploaded.skippedColumns.length==1){
|
|
1340
1358
|
messages.push(my.messages.skippedColumn+": "+result.uploaded.skippedColumns.join(', '));
|
|
1341
1359
|
}else if(result.uploaded.skippedColumns.length>1){
|
package/lib/backend-plus.d.ts
CHANGED
|
@@ -294,6 +294,7 @@ export type TableDefinition = EditableDbDefinition & {
|
|
|
294
294
|
firstDisplayOverLimit?:number
|
|
295
295
|
description?:MarkdownDoc
|
|
296
296
|
exportJsonFieldAsColumns?:string
|
|
297
|
+
importCuidado?:boolean
|
|
297
298
|
}
|
|
298
299
|
export interface DetailTable { table?: string, fields: FieldsForConnectDetailTable, abr: string, label?: string, refreshParent?:boolean, refreshFromParent?:boolean, wScreen?:string, condition?:string }
|
|
299
300
|
export type TableDefinitionFunction = (context: ContextForDump, opts?:any) => TableDefinition;
|
package/lib/backend-plus.js
CHANGED
|
@@ -230,7 +230,7 @@ AppBackend.prototype.i18n.messages.en={
|
|
|
230
230
|
fileUploaded:'file uploaded',
|
|
231
231
|
unkownExt:'unkown file extension'
|
|
232
232
|
},
|
|
233
|
-
server:{
|
|
233
|
+
server:{
|
|
234
234
|
cantDelete_TLDR:'Can\'t delete. May be rights problems, locked records or internal problems',
|
|
235
235
|
cantInsert_TLDR:'Can\'t insert. May be rights problems, locked records or internal problems',
|
|
236
236
|
cantUpdate_TLDR:'Can\'t update. May be rights problems, locked records or internal problems',
|
|
@@ -250,6 +250,7 @@ AppBackend.prototype.i18n.messages.en={
|
|
|
250
250
|
line:'line',
|
|
251
251
|
missingPrimaryKeyValues:'missing primary key values',
|
|
252
252
|
noMailerConfig:'not mailer configurated',
|
|
253
|
+
notInputCuidado:'The uploaded file is not a "#cuidado" file',
|
|
253
254
|
notLoggedIn:'not logged in',
|
|
254
255
|
oldPassDontMatch:'old password does not matchs or username is not longer valid or token is invalid',
|
|
255
256
|
passChangedSuccesfully: 'password was changed successfully',
|
|
@@ -327,6 +328,7 @@ AppBackend.prototype.i18n.messages.es={
|
|
|
327
328
|
line:'linea',
|
|
328
329
|
missingPrimaryKeyValues:'faltan valores en los campos de la clave principal',
|
|
329
330
|
noMailerConfig:'falta la configuración del mailer',
|
|
331
|
+
notInputCuidado:'El archivo no es un archivo "#cuidado"',
|
|
330
332
|
notLoggedIn:'sin inicio de sesión',
|
|
331
333
|
oldPassDontMatch:'la clave anterior no coincide o el usuario es inválido o el token está vencido',
|
|
332
334
|
passChangedSuccesfully: 'password was changed successfully',
|
|
@@ -1127,6 +1129,9 @@ AppBackend.prototype.rootPath = process.cwd();
|
|
|
1127
1129
|
AppBackend.prototype.specialValueWhenInsert = {
|
|
1128
1130
|
currentUsername:function(context){
|
|
1129
1131
|
return context.username;
|
|
1132
|
+
},
|
|
1133
|
+
lineNumberWhenImported:function(_context, _defField, parameters){
|
|
1134
|
+
return parameters.lineNumber
|
|
1130
1135
|
}
|
|
1131
1136
|
}
|
|
1132
1137
|
|
package/lib/procedures-table.js
CHANGED
|
@@ -9,6 +9,8 @@ var typeStore=require('type-store');
|
|
|
9
9
|
var likeAr=require('like-ar');
|
|
10
10
|
const f = require('session-file-store');
|
|
11
11
|
|
|
12
|
+
const PANIC_IMPORT = true;
|
|
13
|
+
|
|
12
14
|
var ProcedureTables;
|
|
13
15
|
|
|
14
16
|
function inlineLog(mmm){ console.log(mmm); return mmm; }
|
|
@@ -437,9 +439,9 @@ ProcedureTables = [
|
|
|
437
439
|
return context.client.query(
|
|
438
440
|
inlineLog(
|
|
439
441
|
"DELETE FROM "+be.db.quoteIdent(defTable.sql.tableName)+
|
|
440
|
-
" WHERE "+whereParts.join(" AND ")),
|
|
442
|
+
" WHERE "+whereParts.join(" AND ")+" RETURNING 1"),
|
|
441
443
|
dataParams
|
|
442
|
-
).
|
|
444
|
+
).fetchUniqueRow().then(function(){
|
|
443
445
|
deleteCounter++;
|
|
444
446
|
context.informProgress({lengthComputable:true, loaded:deleteCounter, total:parameters.rowsToDelete.length});
|
|
445
447
|
});
|
|
@@ -675,9 +677,12 @@ ProcedureTables = [
|
|
|
675
677
|
// console.log('xxxxxxxxxxxxxxx ',files[0].originalFilename);
|
|
676
678
|
var fields=[];
|
|
677
679
|
var otherFieldNames=[];
|
|
680
|
+
var inputCuidado = false;
|
|
678
681
|
var testCandidateColumnAndAddIt=function testCandidateColumnAndAddIt(fieldName, iColumn, cellAddress){
|
|
679
682
|
cellAddress=cellAddress||iColumn;
|
|
680
|
-
if(fieldName
|
|
683
|
+
if(fieldName == "#cuidado"){
|
|
684
|
+
inputCuidado = true;
|
|
685
|
+
}else if(fieldName && fieldName!='#ignore'){
|
|
681
686
|
var fieldName=fieldName.trim();
|
|
682
687
|
if(tableDef.prefix){
|
|
683
688
|
fieldName=tableDef.prefix+'_'+fieldName;
|
|
@@ -737,6 +742,11 @@ ProcedureTables = [
|
|
|
737
742
|
"#null":null,
|
|
738
743
|
"#''":''
|
|
739
744
|
};
|
|
745
|
+
var controlCuidado = function(){
|
|
746
|
+
if(tableDef.importCuidado && !inputCuidado){
|
|
747
|
+
throw new Error(be.messages.server.notInputCuidado);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
740
750
|
if(files[0].originalFilename.match(/\.(tab|txt)$/)){
|
|
741
751
|
readerFunction=fs.readFile(files[0].path,{encoding:'UTF8'}).then(function(content){
|
|
742
752
|
context.informProgress({message:be.messages.server.fileReaded});
|
|
@@ -751,6 +761,7 @@ ProcedureTables = [
|
|
|
751
761
|
heading=lines[0].split(separator);
|
|
752
762
|
}
|
|
753
763
|
heading.forEach(function(col,i){ return testCandidateColumnAndAddIt(col,i); });
|
|
764
|
+
controlCuidado();
|
|
754
765
|
doing="retrieving rows";
|
|
755
766
|
var rowsForUpsert=lines.slice(1).map(function(line){
|
|
756
767
|
var othersArray = [];
|
|
@@ -775,6 +786,9 @@ ProcedureTables = [
|
|
|
775
786
|
newRow[field.name]=value;
|
|
776
787
|
}
|
|
777
788
|
});
|
|
789
|
+
if(inputCuidado){
|
|
790
|
+
newRow['#cuidado'] = row[0];
|
|
791
|
+
}
|
|
778
792
|
newRow = addOtherColumnsToNewRow(newRow, othersArray);
|
|
779
793
|
return newRow;
|
|
780
794
|
});
|
|
@@ -810,6 +824,7 @@ ProcedureTables = [
|
|
|
810
824
|
testCandidateColumnAndAddIt(cellOfFieldName.v,iColumn,cellAddress);
|
|
811
825
|
}
|
|
812
826
|
}
|
|
827
|
+
controlCuidado();
|
|
813
828
|
doing="retrieving rows";
|
|
814
829
|
var rowsForUpsert=[];
|
|
815
830
|
for(var iRow=fieldNameRowNum+1; iRow<=range.e.r; iRow++){
|
|
@@ -854,6 +869,9 @@ ProcedureTables = [
|
|
|
854
869
|
}
|
|
855
870
|
}
|
|
856
871
|
};
|
|
872
|
+
if(inputCuidado){
|
|
873
|
+
newRow['#cuidado'] = (ws[XLSX.utils.encode_cell({r:iRow, c:0})]||{}).v;
|
|
874
|
+
}
|
|
857
875
|
newRow = addOtherColumnsToNewRow(newRow, othersArray);
|
|
858
876
|
rowsForUpsert.push(newRow);
|
|
859
877
|
}
|
|
@@ -865,7 +883,9 @@ ProcedureTables = [
|
|
|
865
883
|
};
|
|
866
884
|
var inserted=0;
|
|
867
885
|
var updated=0;
|
|
886
|
+
var deleted=0;
|
|
868
887
|
var readed=0;
|
|
888
|
+
var skipped=0;
|
|
869
889
|
var total=1;
|
|
870
890
|
var origin=new Date();
|
|
871
891
|
if(tableDef.sql.constraintsDeferred){
|
|
@@ -873,6 +893,7 @@ ProcedureTables = [
|
|
|
873
893
|
await context.client.query("SET CONSTRAINTS ALL DEFERRED").execute();
|
|
874
894
|
}
|
|
875
895
|
return readerFunction.then(async function(rowsAndOtherFieldsNames){
|
|
896
|
+
var importErrors = [];
|
|
876
897
|
var rowsForUpsert = rowsAndOtherFieldsNames.rowsForUpsert;
|
|
877
898
|
total = rowsForUpsert.length;
|
|
878
899
|
var otherFieldNames = rowsAndOtherFieldsNames.otherFieldNames;
|
|
@@ -881,6 +902,19 @@ ProcedureTables = [
|
|
|
881
902
|
var previousRow={};
|
|
882
903
|
let lineNumber = 1;
|
|
883
904
|
for(let newRow of rowsForUpsert){
|
|
905
|
+
var { procedure, insertIfNotUpdate, status } = ({
|
|
906
|
+
false :{procedure:'table_record_save' , status:'update', insertIfNotUpdate: true },
|
|
907
|
+
['#nuevo' ]:{procedure:'table_record_save' , status:'new' , insertIfNotUpdate: false},
|
|
908
|
+
['#cambio']:{procedure:'table_record_save' , status:'update', insertIfNotUpdate: false},
|
|
909
|
+
['#borrar']:{procedure:'table_record_delete', status:'update', insertIfNotUpdate: false},
|
|
910
|
+
})[ inputCuidado && newRow['#cuidado'] ] || {}
|
|
911
|
+
if(inputCuidado){
|
|
912
|
+
delete newRow['#cuidado'];
|
|
913
|
+
}
|
|
914
|
+
if(procedure == null){
|
|
915
|
+
skipped++;
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
884
918
|
var skip=false;
|
|
885
919
|
var hasOneValue=false;
|
|
886
920
|
var primaryKeyValues=[];
|
|
@@ -915,7 +949,7 @@ ProcedureTables = [
|
|
|
915
949
|
}
|
|
916
950
|
if(field.isPk){
|
|
917
951
|
primaryKeyValues[field.isPk-1]=value;
|
|
918
|
-
if(value==null){
|
|
952
|
+
if(value==null && !defField.specialValueWhenInsert){
|
|
919
953
|
throw new Error(be.messages.server.primarKeyCantBeNull4.replace('$1',lineNumber).replace('$2',field.name));
|
|
920
954
|
}
|
|
921
955
|
}
|
|
@@ -944,16 +978,17 @@ ProcedureTables = [
|
|
|
944
978
|
readed++;
|
|
945
979
|
context.informProgress({lengthComputable:true, loaded:readed, total:total});
|
|
946
980
|
try{
|
|
947
|
-
var result = await be.procedure.
|
|
981
|
+
var result = await be.procedure[procedure].coreFunction(
|
|
948
982
|
context,
|
|
949
983
|
{
|
|
950
984
|
table: parameters.table,
|
|
951
985
|
primaryKeyValues,
|
|
952
986
|
newRow,
|
|
953
987
|
oldRow:[],
|
|
954
|
-
status
|
|
955
|
-
insertIfNotUpdate
|
|
956
|
-
masive:true
|
|
988
|
+
status,
|
|
989
|
+
insertIfNotUpdate,
|
|
990
|
+
masive:true,
|
|
991
|
+
lineNumber
|
|
957
992
|
},
|
|
958
993
|
null,
|
|
959
994
|
{forImport:true}
|
|
@@ -962,10 +997,28 @@ ProcedureTables = [
|
|
|
962
997
|
inserted++;
|
|
963
998
|
}else if(result.command==='UPDATE'){
|
|
964
999
|
updated++;
|
|
1000
|
+
}else if(procedure=='table_record_delete'){
|
|
1001
|
+
deleted++;
|
|
965
1002
|
}
|
|
966
1003
|
}catch(err){
|
|
967
1004
|
err.detail=be.messages.server.line+' '+lineNumber+' / '+tableDef.primaryKey+' = '+JSON.stringify(primaryKeyValues);
|
|
968
|
-
|
|
1005
|
+
if(PANIC_IMPORT){
|
|
1006
|
+
throw err;
|
|
1007
|
+
}else{
|
|
1008
|
+
importErrors.push(err);
|
|
1009
|
+
try{
|
|
1010
|
+
await context.client.query('ROLLBACK').execute();
|
|
1011
|
+
}catch(err2){
|
|
1012
|
+
err.detail+=' *** in ROLLBACK ' + err2.message;
|
|
1013
|
+
throw err
|
|
1014
|
+
}
|
|
1015
|
+
try{
|
|
1016
|
+
await context.client.query("BEGIN TRANSACTION").execute();
|
|
1017
|
+
}catch(err2){
|
|
1018
|
+
err.detail+=' *** in BEGIN TRANSACTION ' + err2.message;
|
|
1019
|
+
throw err
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
969
1022
|
};
|
|
970
1023
|
}
|
|
971
1024
|
previousRow=newRow;
|
|
@@ -987,28 +1040,32 @@ ProcedureTables = [
|
|
|
987
1040
|
for(let pkOtherField of otherFieldsTableDef.primaryKey){
|
|
988
1041
|
primaryKeyValues.push(newRow[pkOtherField]);
|
|
989
1042
|
};
|
|
990
|
-
await be.procedure.
|
|
1043
|
+
await be.procedure[procedure].coreFunction(
|
|
991
1044
|
context,{
|
|
992
1045
|
table: otherFieldsTableDef.name,
|
|
993
1046
|
primaryKeyValues,
|
|
994
1047
|
newRow,
|
|
995
1048
|
oldRow:[],
|
|
996
|
-
status
|
|
997
|
-
insertIfNotUpdate
|
|
1049
|
+
status,
|
|
1050
|
+
insertIfNotUpdate,
|
|
998
1051
|
masive:true
|
|
999
1052
|
}
|
|
1000
1053
|
);
|
|
1001
1054
|
};
|
|
1002
1055
|
}
|
|
1056
|
+
if(importErrors.length){
|
|
1057
|
+
await context.client.query('ROLLBACK').execute();
|
|
1058
|
+
return {json:{importErrors}};
|
|
1059
|
+
}
|
|
1003
1060
|
context.informProgress({message:be.messages.insertingRows});
|
|
1004
|
-
}).then(async function(){
|
|
1061
|
+
}).then(async function(other){
|
|
1005
1062
|
context.informProgress({message:be.messages.checkingConstraints});
|
|
1006
1063
|
if(tableDef.sql.constraintsDeferred){
|
|
1007
1064
|
await context.client.query("SET CONSTRAINTS ALL IMMEDIATE").execute();
|
|
1008
1065
|
await recreateConstraints(tableDef, true);
|
|
1009
1066
|
}
|
|
1010
1067
|
context.informProgress({lengthComputable:true, loaded:readed, total:total, force:true});
|
|
1011
|
-
return {uploaded:{inserted,updated,skippedColumns}};
|
|
1068
|
+
return other || {uploaded:{inserted,updated,skipped,deleted,skippedColumns}};
|
|
1012
1069
|
});
|
|
1013
1070
|
}).catch(function(err){
|
|
1014
1071
|
console.log('ERROR',err.message);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-plus",
|
|
3
3
|
"description": "Backend for typed controls",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.16.2",
|
|
5
5
|
"author": "Codenautas <codenautas@googlegroups.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "codenautas/backend-plus",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"backend-skins": "^0.1.15",
|
|
33
33
|
"best-globals": "^1.0.3",
|
|
34
34
|
"big.js": "^6.1.1",
|
|
35
|
-
"body-parser": "^1.
|
|
35
|
+
"body-parser": "^1.20.0",
|
|
36
36
|
"cast-error": "^0.1.0",
|
|
37
37
|
"castellano": "^0.1.3",
|
|
38
38
|
"connect-pg-simple": "^7.0.0",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"login-plus": "^1.6.2",
|
|
53
53
|
"memorystore": "^1.6.7",
|
|
54
54
|
"mini-tools": "^1.11.2",
|
|
55
|
-
"nodemailer": "^6.7.
|
|
56
|
-
"moment": "^2.29.
|
|
55
|
+
"nodemailer": "^6.7.3",
|
|
56
|
+
"moment": "^2.29.2",
|
|
57
57
|
"multiparty": "^4.2.3",
|
|
58
58
|
"numeral": "^2.0.6",
|
|
59
59
|
"pg-promise-strict": "^1.2.6",
|
|
@@ -65,12 +65,12 @@
|
|
|
65
65
|
"self-explain": "^0.10.22",
|
|
66
66
|
"serve-content": "^0.3.17",
|
|
67
67
|
"session-file-store": "^1.5.0",
|
|
68
|
-
"sql-tools": "^0.1.
|
|
68
|
+
"sql-tools": "^0.1.2",
|
|
69
69
|
"stack-trace": "^0.0.10",
|
|
70
|
-
"stylus": "^0.
|
|
70
|
+
"stylus": "^0.57.0",
|
|
71
71
|
"type-store": "^0.2.41",
|
|
72
72
|
"typed-controls": "^0.10.0",
|
|
73
|
-
"xlsx": "^0.18.
|
|
73
|
+
"xlsx": "^0.18.5",
|
|
74
74
|
"xlsx-style": "^0.8.13"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@types/mocha": "^9.1.0",
|
|
84
84
|
"@types/nodemailer": "^6.4.4",
|
|
85
85
|
"@types/multiparty": "~0.0.33",
|
|
86
|
-
"@types/node": "^17.0.
|
|
86
|
+
"@types/node": "^17.0.23",
|
|
87
87
|
"@types/numeral": "~2.0.2",
|
|
88
88
|
"@types/session-file-store": "^1.2.2",
|
|
89
89
|
"@types/stack-trace": "~0.0.29",
|
|
@@ -91,19 +91,19 @@
|
|
|
91
91
|
"esprima": "^4.0.1",
|
|
92
92
|
"expect.js": "~0.3.1",
|
|
93
93
|
"karma": "6.3.17",
|
|
94
|
-
"karma-chrome-launcher": "^3.1.
|
|
94
|
+
"karma-chrome-launcher": "^3.1.1",
|
|
95
95
|
"karma-expect": "^1.1.3",
|
|
96
96
|
"karma-firefox-launcher": "^2.1.2",
|
|
97
97
|
"karma-ie-launcher": "^1.0.0",
|
|
98
98
|
"karma-mocha": "^2.0.1",
|
|
99
99
|
"kill-9": "~0.4.3",
|
|
100
|
-
"mocha": "^9.2.
|
|
100
|
+
"mocha": "^9.2.2",
|
|
101
101
|
"nyc": "^15.1.0",
|
|
102
|
-
"puppeteer": "^13.
|
|
102
|
+
"puppeteer": "^13.5.2",
|
|
103
103
|
"sinon": "^13.0.1",
|
|
104
104
|
"supertest": "^6.2.2",
|
|
105
105
|
"types.d.ts": "~0.6.7",
|
|
106
|
-
"typescript": "^4.6.
|
|
106
|
+
"typescript": "^4.6.3",
|
|
107
107
|
"why-is-node-running": "^2.2.1"
|
|
108
108
|
},
|
|
109
109
|
"engines": {
|
|
@@ -117,6 +117,7 @@
|
|
|
117
117
|
"test-good": "mocha --reporter spec --bail --check-leaks test/test*.js",
|
|
118
118
|
"example-pu": "node test/puppeteer/first-step.js",
|
|
119
119
|
"test-pu": "mocha --reporter spec --bail --check-leaks --globals cptable --globals QUOTE --globals __core-js_shared__ test/test-pu.js",
|
|
120
|
+
"test-server": "mocha --reporter spec --single-run --bail test/test.js",
|
|
120
121
|
"server-test": "node test/run-simple-backend.js",
|
|
121
122
|
"example-tables": "node examples/tables/server/server-tables.js --dir-x examples/tables",
|
|
122
123
|
"example-fichas": "node examples/fichero/server/server-fichas.js",
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @function
|
|
3
|
-
* @template T extends {}
|
|
4
|
-
* @param {T & {name?:string|null|undefined}} obj
|
|
5
|
-
* @param {string} n
|
|
6
|
-
* @return {obj is T}
|
|
7
|
-
*/
|
|
8
|
-
function addName(obj, n) {
|
|
9
|
-
obj.name = n;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
let thing = {size: "medium"};
|
|
13
|
-
addName(thing, "product");
|
|
14
|
-
var other = thing;
|
|
15
|
-
console.log(thing.name);
|