pogi 2.11.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.
- package/.vscode/launch.json +35 -0
- package/CHANGELOG.md +277 -0
- package/LICENSE +21 -0
- package/README.md +85 -0
- package/docs/API/PgDb.md +218 -0
- package/docs/API/PgSchema.md +91 -0
- package/docs/API/PgTable.md +365 -0
- package/docs/API/QueryOptions.md +77 -0
- package/docs/API/condition.md +133 -0
- package/docs/connection.md +91 -0
- package/docs/css/docs.css +164 -0
- package/docs/executingSqlFile.md +44 -0
- package/docs/faq.md +15 -0
- package/docs/functions.md +19 -0
- package/docs/generatingInterfaceForTables.md +35 -0
- package/docs/index.md +48 -0
- package/docs/logger.md +40 -0
- package/docs/mappingDatabaseTypes.md +89 -0
- package/docs/notification.md +19 -0
- package/docs/pitfalls.md +73 -0
- package/docs/streams.md +68 -0
- package/docs/transaction.md +65 -0
- package/lib/bin/generateInterface.d.ts +1 -0
- package/lib/bin/generateInterface.js +53 -0
- package/lib/bin/generateInterface.js.map +1 -0
- package/lib/connectionOptions.d.ts +25 -0
- package/lib/connectionOptions.js +3 -0
- package/lib/connectionOptions.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.js +10 -0
- package/lib/index.js.map +1 -0
- package/lib/pgConverters.d.ts +10 -0
- package/lib/pgConverters.js +66 -0
- package/lib/pgConverters.js.map +1 -0
- package/lib/pgDb.d.ts +86 -0
- package/lib/pgDb.js +745 -0
- package/lib/pgDb.js.map +1 -0
- package/lib/pgDbLogger.d.ts +5 -0
- package/lib/pgDbLogger.js +3 -0
- package/lib/pgDbLogger.js.map +1 -0
- package/lib/pgDbOperators.d.ts +113 -0
- package/lib/pgDbOperators.js +44 -0
- package/lib/pgDbOperators.js.map +1 -0
- package/lib/pgSchema.d.ts +16 -0
- package/lib/pgSchema.js +16 -0
- package/lib/pgSchema.js.map +1 -0
- package/lib/pgTable.d.ts +131 -0
- package/lib/pgTable.js +322 -0
- package/lib/pgTable.js.map +1 -0
- package/lib/pgUtils.d.ts +31 -0
- package/lib/pgUtils.js +157 -0
- package/lib/pgUtils.js.map +1 -0
- package/lib/queryAble.d.ts +76 -0
- package/lib/queryAble.js +330 -0
- package/lib/queryAble.js.map +1 -0
- package/lib/queryWhere.d.ts +8 -0
- package/lib/queryWhere.js +249 -0
- package/lib/queryWhere.js.map +1 -0
- package/mkdocs.yml +25 -0
- package/package.json +65 -0
- package/spec/resources/init.sql +122 -0
- package/spec/resources/throw_exception.sql +5 -0
- package/spec/resources/tricky.sql +13 -0
- package/spec/run.js +5 -0
- package/spec/support/jasmine.json +9 -0
- package/src/bin/generateInterface.ts +54 -0
- package/src/connectionOptions.ts +42 -0
- package/src/index.ts +6 -0
- package/src/pgConverters.ts +55 -0
- package/src/pgDb.ts +820 -0
- package/src/pgDbLogger.ts +13 -0
- package/src/pgDbOperators.ts +62 -0
- package/src/pgSchema.ts +15 -0
- package/src/pgTable.ts +401 -0
- package/src/pgUtils.ts +176 -0
- package/src/queryAble.ts +393 -0
- package/src/queryWhere.ts +326 -0
- package/src/test/pgDbOperatorSpec.ts +492 -0
- package/src/test/pgDbSpec.ts +1339 -0
- package/src/test/pgServiceRestartTest.ts +1500 -0
- package/src/tsconfig.json +33 -0
- package/utils_sql/lower.sql +4 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
##SqlQueryOption, InsertOption
|
|
2
|
+
You can set the logger.
|
|
3
|
+
```js
|
|
4
|
+
export interface SqlQueryOptions {
|
|
5
|
+
logger?: PgDbLogger;
|
|
6
|
+
}
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
##QueryOptions
|
|
10
|
+
Query (`select`) option has to follow the following interface:
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
interface QueryOptions {
|
|
14
|
+
limit?:number;
|
|
15
|
+
offset?: number;
|
|
16
|
+
orderBy?: string|string[]|{[fieldName:string]:'asc'|'desc'};//free text or column list
|
|
17
|
+
groupBy?:string|string[]; //free text or column list
|
|
18
|
+
fields?: string|string[]; //free text or column list
|
|
19
|
+
skipUndefined?:boolean; //if there is an undefined value in the conditions, shall it be skipped. Default raise error.
|
|
20
|
+
logger?:PgDbLogger;
|
|
21
|
+
distinct?: boolean; // SELECT DISTINCT statement
|
|
22
|
+
forUpdate?: boolean; // FOR UPDATE statement
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
where orderBy/groupBy/fields can be either an array (in that case will get quotation if needed)
|
|
26
|
+
or a free text string with all the possibilities.
|
|
27
|
+
|
|
28
|
+
logger can be specified for the current query only.
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
await pgdb.users.find({medal:['g','s','b']}, {orderBy:'sum(*)', groupBy:['country'], fields:'sum(*) as numberOfMedals, country'});
|
|
32
|
+
```
|
|
33
|
+
### orderBy
|
|
34
|
+
You can do as you like:
|
|
35
|
+
```js
|
|
36
|
+
await pgdb.users.find({}, {orderBy:{name:'desc', ageCategory:'asc'}});
|
|
37
|
+
await pgdb.users.find({}, {orderBy:['name desc', 'ageCategory asc']});
|
|
38
|
+
await pgdb.users.find({}, {orderBy:['-name', '+ageCategory']});
|
|
39
|
+
await pgdb.users.find({}, {orderBy:['name', 'ageCategory']});
|
|
40
|
+
await pgdb.users.find({}, {orderBy:'name dec, "ageCategory" asc'});
|
|
41
|
+
```
|
|
42
|
+
### groupBy
|
|
43
|
+
```js
|
|
44
|
+
await pgdb.users.find({}, {groupBy:'name, "ageCategory", count(*)'});
|
|
45
|
+
await pgdb.users.find({}, {groupBy:['name', 'ageCategory', 'count(*)']});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### skipUndefined
|
|
49
|
+
```js
|
|
50
|
+
await pgdb.users.find({}, {name:'joe', password:undefined}); //raise error
|
|
51
|
+
await pgdb.users.find({}, {name:'joe', password:undefined}, {skipUndefined:true}); //return the record with name 'joe'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
##UpdateDeleteOption
|
|
55
|
+
```js
|
|
56
|
+
export interface SqlQueryOptions {
|
|
57
|
+
skipUndefined?:boolean; //if there is an undefined value in the conditions, shall it be skipped. Default raise error.
|
|
58
|
+
logger?: PgDbLogger;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## & Return, & Stream
|
|
63
|
+
Additional interfaces to set return value type.
|
|
64
|
+
|
|
65
|
+
With `stream:true` query will return with stream instead of the populated result.
|
|
66
|
+
|
|
67
|
+
With `return *` insert / update / delete query will return the affected rows (this is the default).
|
|
68
|
+
|
|
69
|
+
`return string[]` is the same as '*' but only return with the specified columns
|
|
70
|
+
```js
|
|
71
|
+
export interface Return {
|
|
72
|
+
return?:string[]|'*';
|
|
73
|
+
}
|
|
74
|
+
export interface Stream {
|
|
75
|
+
stream: true;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#Conditions and operators
|
|
2
|
+
|
|
3
|
+
##Basic examples
|
|
4
|
+
|
|
5
|
+
| Condition | SQL
|
|
6
|
+
| ------------- |:--------------
|
|
7
|
+
| {id: 2} | "id" = 2
|
|
8
|
+
| {'id <': 2} | "id" < 2
|
|
9
|
+
| {'id >': 2} | "id" > 2
|
|
10
|
+
| {'id <=': 2} | "id" <= 2
|
|
11
|
+
| {'id >=': 2} | "id" >= 2
|
|
12
|
+
| {'id !=': 2} | "id" != 2
|
|
13
|
+
| {'id <>': 2} | "id" != 2
|
|
14
|
+
| {'id': null} | "id" is null
|
|
15
|
+
| {'id !=': null} | "id" is not null
|
|
16
|
+
| {'id is not': null}| "id" is not null
|
|
17
|
+
| {'id in':[1,2,3]} | "id" in (1,2,3)
|
|
18
|
+
| {'id not in':[1,2,3]}| "id" not in (1,2,3)
|
|
19
|
+
|
|
20
|
+
###Extended
|
|
21
|
+
|
|
22
|
+
| Condition | SQL
|
|
23
|
+
| ------------- |:--------------
|
|
24
|
+
| {id: [1,2,3]} | "id" in (1,2,3)
|
|
25
|
+
| {'id <>': [1,2,3]} | "id" not in (1,2,3)
|
|
26
|
+
| {'id =*':'gamma'} | LOWER("id") = LOWER('gamma')
|
|
27
|
+
| {'fruits =*':'KiWi'} | LOWER("fruits") && '{kiwi}' //Has to have the LOWER function defined see below. (It uses GIN index if defined on fruits)
|
|
28
|
+
|
|
29
|
+
##Pattern matching
|
|
30
|
+
[PostgreSQL Documentation](https://www.postgresql.org/docs/9.6/static/functions-matching.html)
|
|
31
|
+
|
|
32
|
+
| Condition | SQL
|
|
33
|
+
| ------------- |:--------------
|
|
34
|
+
| {'id ~~': 'a%'} | "id" LIKE 'a%'
|
|
35
|
+
| {'id !~~': 'a%'} | "id" NOT LIKE 'a%'
|
|
36
|
+
| {'id like': 'a%'} | "id" LIKE 'a%'
|
|
37
|
+
| {'id not like': 'a%'} | "id" NOT LIKE 'a%'
|
|
38
|
+
| {'id ~~*': 'a%'} | "id" ILIKE 'a%'
|
|
39
|
+
| {'id !~~*': 'a%'} | "id" NOT ILIKE 'a%'
|
|
40
|
+
| {'id ilike': 'a%'} | "id" ILIKE 'a%'
|
|
41
|
+
| {'id not ilike': 'a%'} | "id" NOT ILIKE 'a%'
|
|
42
|
+
| {'id similar to': 'a%'} | "id" SIMILAR TO 'a%'
|
|
43
|
+
| {'id not similar to': 'a%'} | "id" NOT SIMILAR TO 'a%'
|
|
44
|
+
| {'id ~': '^a'} | "id" ~ '^a'
|
|
45
|
+
| {'id !~': '^a'} | "id" !~ '^a'
|
|
46
|
+
| {'id ~*': '^a'} | "id" ~* '^a'
|
|
47
|
+
| {'id !~*': '^a'} | "id" !~* '^a'
|
|
48
|
+
| {'id is distinct from': '^a'}| "id" IS DISTINCT FROM '^a'
|
|
49
|
+
| {'id is not distinct from': '^a'}| "id" IS NOT DISTINCT FROM '^a'
|
|
50
|
+
|
|
51
|
+
###Extended
|
|
52
|
+
|
|
53
|
+
| Condition | SQL
|
|
54
|
+
| ------------- |:--------------
|
|
55
|
+
| {'id ~~': ['1%','2%','3%']} | "id" LIKE ANY('{1%,2%,3%}')
|
|
56
|
+
| {'id !~~': ['1%','2%','3%']}| "id" NOT LIKE ALL('{1%,2%,3%}')
|
|
57
|
+
| {'id ~': ['^1','^2','^3']} | "id" LIKE ANY('{^1,^2,^3}')
|
|
58
|
+
| {'id !~': ['^1','^2','^3']} | "id" NOT LIKE ALL('{^1,^2,^3}')
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
##Array type
|
|
62
|
+
[PostgreSQL Documentation](https://www.postgresql.org/docs/current/static/functions-array.html)
|
|
63
|
+
|
|
64
|
+
| Condition | SQL | note
|
|
65
|
+
| ------------- |:-------------- | :--------------
|
|
66
|
+
| {'ids @>':[1,2,3]} | "ids" @> '{1,2,3}' | ids contains all of 1,2,3
|
|
67
|
+
| {'ids <@':[1,2,3]} | "ids" <@ '{1,2,3}' | ids is a subset of {1,2,3}
|
|
68
|
+
| {'ids &&':[1,2,3]} | "ids" && '{1,2,3}' | ids overlaps with {1,2,3}
|
|
69
|
+
| {'ids': [1,2,3]} | "ids" = '{1,2,3}' |
|
|
70
|
+
| {'ids': 'a'} | 'a' = ANY("ids") |
|
|
71
|
+
| {'ids <>': 'a'} | 'a' <> ANY("ids") |
|
|
72
|
+
|
|
73
|
+
Please note that as-of-9.5 `'a' = ANY("ids")` is not using the index in psql. So if have a `GIN` index is defined on the column "ids",
|
|
74
|
+
You should use `{'ids &&': ['a']}` (that is translated to `"ids" && '{a}'`).
|
|
75
|
+
|
|
76
|
+
###Extended
|
|
77
|
+
| Condition | SQL
|
|
78
|
+
| ------------- |:--------------
|
|
79
|
+
| {'ids ~': 'a%'} | EXISTS (SELECT * FROM (SELECT UNNEST("ids") _el) _arr WHERE _arr._el ~ 'a%')'; //same with all pattern matching operator
|
|
80
|
+
| {'names &&*': ['A','B','C']} | LOWER("names") && '{a, b, c}' //case insensitive overlap operator, has to have the LOWER function defined for arrays (see below)
|
|
81
|
+
|
|
82
|
+
##Jsonb type
|
|
83
|
+
[PostgreSQL Documentation](https://www.postgresql.org/docs/current/static/functions-json.html)
|
|
84
|
+
|
|
85
|
+
| Condition | SQL | NOTE
|
|
86
|
+
| ------------- |:-------------- |:---
|
|
87
|
+
| {'jdata @>':[1,2,3]} | "jdata" @> '[1,2,3]' |
|
|
88
|
+
| {'jdata @>':{a:1}} | "jdata" @> '{a:1}' |
|
|
89
|
+
| {'jdata <@':[1,2,3]} | "jdata" <@ '[1,2,3]' |
|
|
90
|
+
| {'jdata <@':{a:1}} | "jdata" <@ '{a:1}' |
|
|
91
|
+
| {'jdata ?':'a'} | "jdata" ? 'a' |
|
|
92
|
+
| {'jdata ?|':['a','b']}| "jdata" ?| '{a,b}' |
|
|
93
|
+
| {'jdata ?&':['a','b']} | "jdata" ?& '{a,b}' |
|
|
94
|
+
| {'jdata -> a':{a:3}} | "jdata" -> 'a' = '{"a":3}'::jsonb |
|
|
95
|
+
| {'jdata -> 3':{a:3}} | "jdata" -> 3 = '{"a":3}'::jsonb |if the field is a number, the quote wont apply as it could refer index also
|
|
96
|
+
| {"jdata -> '3'":{a:3}} | "jdata" -> '3' = '{"a":3}'::jsonb |... so you have to apply that manually
|
|
97
|
+
| {'jdata ->> a':3} | "jdata" ->>'a' = 3 |
|
|
98
|
+
| {'jdata ->> 3':3} | "jdata" ->> 3 = 3 |if the field is a number, the quote wont apply as it could refer index also
|
|
99
|
+
| {'jdata ->> '3'":'{"a": 3}'} | "jdata"->>3 = '{"a": 3}' |... so you have to apply that manually
|
|
100
|
+
| {"jdata #> '{a,3}'":{a:3}} | "jdata"#>'{a,3}' = '{"a":3}'::jsonb|surronding {} with ' is possible but not obligatory
|
|
101
|
+
| {"jdata #>> {a,3}":'{"a": 3}'} | "jdata"#>>'{a,3}' = '{"a": 3}' |
|
|
102
|
+
| {"jdata #>> {a} >":'a' | "jdata"#>>'{a}' > 'a' |
|
|
103
|
+
|
|
104
|
+
Note:
|
|
105
|
+
|
|
106
|
+
`->`,`#>` returns as a JsonObject
|
|
107
|
+
|
|
108
|
+
`->>`, `#>>` returns as a string.
|
|
109
|
+
|
|
110
|
+
At the moment they are not converted automatically thou, for `->>` you should use JSON.stringify if needed.
|
|
111
|
+
(this is a later todo, you can help us! :), same goes for `->`, it not converted automaticaly if not an object passed in, but a number or string)
|
|
112
|
+
|
|
113
|
+
## AND - OR
|
|
114
|
+
condition-expressions can be joined together e.g.:
|
|
115
|
+
|
|
116
|
+
| Condition | SQL
|
|
117
|
+
| ------------- |:--------------
|
|
118
|
+
| {id:1, name:'a'} | id=1 AND name='a'
|
|
119
|
+
| {or: [{id:1}, {name:'a'}]} | id=1 OR name='a'
|
|
120
|
+
| {and: [<br/> or: [{id:1}, {'port >':'1024'}], <br/> or: [{host:'localhost', os:'linux'}, {host:'127.0.0.1'}]<br>]} | (.. OR ..) AND ((.. AND ..) OR ..)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# Definition of LOWER function for array type
|
|
124
|
+
CREATE OR REPLACE FUNCTION LOWER(text[]) RETURNS text[] LANGUAGE SQL IMMUTABLE AS
|
|
125
|
+
$$
|
|
126
|
+
SELECT array_agg(LOWER(value)) FROM unnest($1) value;
|
|
127
|
+
$$;
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
##Connection
|
|
2
|
+
|
|
3
|
+
### Connection with connectionString
|
|
4
|
+
|
|
5
|
+
``` js
|
|
6
|
+
let pgdb = await PgDb.connect({connectionString:'postgres://username@hostname/database', logger:console});
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
where username/hostname/database are all optional. It could be provided through environment variables (EXPORT).
|
|
10
|
+
|
|
11
|
+
### Connection with Options Object
|
|
12
|
+
``` js
|
|
13
|
+
let pgdb = await PgDb.connect({
|
|
14
|
+
host: 'localhost',
|
|
15
|
+
user: 'localuser',
|
|
16
|
+
database: 'localdatabase',
|
|
17
|
+
password: 'localpassword',
|
|
18
|
+
port: 5432,
|
|
19
|
+
max: 10,
|
|
20
|
+
logger:console,
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
With the following options:
|
|
25
|
+
``` js
|
|
26
|
+
export interface ConnectionOptions {
|
|
27
|
+
//--- node-postgres specific ----------------------
|
|
28
|
+
host?:string;
|
|
29
|
+
user?:string; //can be specified through PGUSER env variable (defaults USER env var)
|
|
30
|
+
database?:string; //can be specified through PGDATABASE env variable (defaults USER env var)
|
|
31
|
+
password?:string; //can be specified through PGPASSWORD env variable
|
|
32
|
+
port?:number; //can be specified through PGPORT env variable
|
|
33
|
+
connectionString?:string; //'postgres://username:password@hostname/database'
|
|
34
|
+
|
|
35
|
+
poolSize?:number; //number of connections to use in connection pool. 0 - disable pooling
|
|
36
|
+
min?:number; //minimum number of resources to keep in pool at any given time.
|
|
37
|
+
max?:number;
|
|
38
|
+
reapIntervalMillis?:number; //frequency to check for idle clients within the client pool
|
|
39
|
+
poolLog?:boolean; //pool log function / boolean
|
|
40
|
+
idleTimeoutMillis?:number; // how long a client is allowed to remain idle before being closed
|
|
41
|
+
poolIdleTimeout?:number;
|
|
42
|
+
|
|
43
|
+
rows?:number; //number of rows to return at a time from a prepared statement's portal. 0 will return all rows at once
|
|
44
|
+
binary?:boolean;
|
|
45
|
+
client_encoding?:string;
|
|
46
|
+
ssl?:boolean| any; // TlsOptions;
|
|
47
|
+
application_name?:string;
|
|
48
|
+
fallback_application_name?:string;
|
|
49
|
+
parseInputDatesAsUTC?:boolean;
|
|
50
|
+
|
|
51
|
+
//--- pogi specific ----------------------------
|
|
52
|
+
logger?:PgDbLogger;
|
|
53
|
+
skipUndefined?: 'all' | 'select' | 'none'; //if there is a undefined value in the query condition, what should pogi do. Default is 'none', meaning raise an error if a value is undefined.
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
About node-postgres specific, more explanation can be found at
|
|
58
|
+
https://github.com/brianc/node-postgres/blob/f6c40b9331c90d794d5fcbb1d4ae2f28eabd4d42/lib/defaults.js
|
|
59
|
+
and
|
|
60
|
+
https://github.com/coopernurse/node-pool
|
|
61
|
+
|
|
62
|
+
##skipUndefined
|
|
63
|
+
while most settings are self explanatory, this parameter is important. In the first version of pogi
|
|
64
|
+
we ignored the condition if the value was undefined (null was not ignored) in order for ease the use e.g.:
|
|
65
|
+
``` ts
|
|
66
|
+
let query = {
|
|
67
|
+
powerfull: params.powerfull,
|
|
68
|
+
wise: params.wise
|
|
69
|
+
}
|
|
70
|
+
await pgdb.users.find(query);
|
|
71
|
+
```
|
|
72
|
+
would return a result if e.g. the `form.wise` would be undefined. While this is comfortable
|
|
73
|
+
in many situation, it can cause critical issues e.g. for update
|
|
74
|
+
``` ts
|
|
75
|
+
await pgdb.users.update({id:user.id}, {password});
|
|
76
|
+
```
|
|
77
|
+
would update all users password, in case of the id is undefined. (Although this can be mitigated
|
|
78
|
+
with the `updateOne` function as well.) Still the best if no undefined value is allowed in the conditions.
|
|
79
|
+
Nevertheless to keep the compatibility, this parameter added, and skipUndefined can be set to `all` if needed.
|
|
80
|
+
`select` would allow undefined values for selects/count only but would be strict for update/deletes.
|
|
81
|
+
`none` is the new default value, meaning undefined value considered as programming error and will throw an exception.
|
|
82
|
+
This setting can be specified on query level as well.
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
### Static singleton
|
|
86
|
+
If there is no reference kept to the object there is a static function to get the same object everywhere,
|
|
87
|
+
(so no need to keep recreating and set up every time). At the moment doesnt handle env variables beside password.
|
|
88
|
+
|
|
89
|
+
``` js
|
|
90
|
+
let pgdb = await PgDb.getInstance({connectionString:'postgres://username@hostname/database', logger:console});
|
|
91
|
+
```
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
.func{
|
|
2
|
+
color:black;
|
|
3
|
+
}
|
|
4
|
+
.type{
|
|
5
|
+
color:chocolate;
|
|
6
|
+
}
|
|
7
|
+
.def{
|
|
8
|
+
color:purple;
|
|
9
|
+
font-weight: bold;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Obsidian style
|
|
15
|
+
* ported by Alexander Marenin (http://github.com/ioncreature)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
.hljs {
|
|
19
|
+
display: block;
|
|
20
|
+
overflow-x: auto;
|
|
21
|
+
padding: 0.5em;
|
|
22
|
+
background: #282b2e;
|
|
23
|
+
-webkit-text-size-adjust: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.hljs-keyword,
|
|
27
|
+
.hljs-literal,
|
|
28
|
+
.hljs-change,
|
|
29
|
+
.hljs-winutils,
|
|
30
|
+
.hljs-flow,
|
|
31
|
+
.nginx .hljs-title,
|
|
32
|
+
.css .hljs-id,
|
|
33
|
+
.tex .hljs-special {
|
|
34
|
+
color: #93c763;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.hljs-number {
|
|
38
|
+
color: #ffcd22;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.hljs {
|
|
42
|
+
color: #e0e2e4;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.css .hljs-tag,
|
|
46
|
+
.css .hljs-pseudo {
|
|
47
|
+
color: #d0d2b5;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.hljs-attribute,
|
|
51
|
+
.hljs .hljs-constant {
|
|
52
|
+
color: #668bb0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.xml .hljs-attribute {
|
|
56
|
+
color: #b3b689;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.xml .hljs-tag .hljs-value {
|
|
60
|
+
color: #e8e2b7;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.hljs-code,
|
|
64
|
+
.hljs-class .hljs-title,
|
|
65
|
+
.hljs-header {
|
|
66
|
+
color: white;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.hljs-class,
|
|
70
|
+
.hljs-hexcolor {
|
|
71
|
+
color: #93c763;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.hljs-regexp {
|
|
75
|
+
color: #d39745;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.hljs-at_rule,
|
|
79
|
+
.hljs-at_rule .hljs-keyword {
|
|
80
|
+
color: #a082bd;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.hljs-doctype {
|
|
84
|
+
color: #557182;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.hljs-link_url,
|
|
88
|
+
.hljs-tag,
|
|
89
|
+
.hljs-tag .hljs-title,
|
|
90
|
+
.hljs-bullet,
|
|
91
|
+
.hljs-subst,
|
|
92
|
+
.hljs-emphasis,
|
|
93
|
+
.hljs-type,
|
|
94
|
+
.hljs-preprocessor,
|
|
95
|
+
.hljs-pragma,
|
|
96
|
+
.ruby .hljs-class .hljs-parent,
|
|
97
|
+
.hljs-built_in,
|
|
98
|
+
.django .hljs-template_tag,
|
|
99
|
+
.django .hljs-variable,
|
|
100
|
+
.smalltalk .hljs-class,
|
|
101
|
+
.django .hljs-filter .hljs-argument,
|
|
102
|
+
.smalltalk .hljs-localvars,
|
|
103
|
+
.smalltalk .hljs-array,
|
|
104
|
+
.hljs-attr_selector,
|
|
105
|
+
.hljs-pseudo,
|
|
106
|
+
.hljs-addition,
|
|
107
|
+
.hljs-stream,
|
|
108
|
+
.hljs-envvar,
|
|
109
|
+
.apache .hljs-tag,
|
|
110
|
+
.apache .hljs-cbracket,
|
|
111
|
+
.tex .hljs-command,
|
|
112
|
+
.hljs-prompt,
|
|
113
|
+
.hljs-name {
|
|
114
|
+
color: #8cbbad;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.hljs-string {
|
|
118
|
+
color: #ec7600;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.hljs-comment,
|
|
122
|
+
.hljs-annotation,
|
|
123
|
+
.hljs-blockquote,
|
|
124
|
+
.hljs-horizontal_rule,
|
|
125
|
+
.hljs-decorator,
|
|
126
|
+
.hljs-pi,
|
|
127
|
+
.hljs-deletion,
|
|
128
|
+
.hljs-shebang,
|
|
129
|
+
.apache .hljs-sqbracket,
|
|
130
|
+
.tex .hljs-formula {
|
|
131
|
+
color: #818e96;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.hljs-keyword,
|
|
135
|
+
.hljs-literal,
|
|
136
|
+
.css .hljs-id,
|
|
137
|
+
.hljs-doctag,
|
|
138
|
+
.hljs-title,
|
|
139
|
+
.hljs-header,
|
|
140
|
+
.hljs-type,
|
|
141
|
+
.vbscript .hljs-built_in,
|
|
142
|
+
.rsl .hljs-built_in,
|
|
143
|
+
.smalltalk .hljs-class,
|
|
144
|
+
.diff .hljs-header,
|
|
145
|
+
.hljs-chunk,
|
|
146
|
+
.hljs-winutils,
|
|
147
|
+
.bash .hljs-variable,
|
|
148
|
+
.apache .hljs-tag,
|
|
149
|
+
.tex .hljs-special,
|
|
150
|
+
.hljs-request,
|
|
151
|
+
.hljs-at_rule .hljs-keyword,
|
|
152
|
+
.hljs-status {
|
|
153
|
+
font-weight: normal;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.coffeescript .javascript,
|
|
157
|
+
.javascript .xml,
|
|
158
|
+
.tex .hljs-formula,
|
|
159
|
+
.xml .javascript,
|
|
160
|
+
.xml .vbscript,
|
|
161
|
+
.xml .css,
|
|
162
|
+
.xml .hljs-cdata {
|
|
163
|
+
opacity: 0.5;
|
|
164
|
+
}
|